home *** CD-ROM | disk | FTP | other *** search
/ Gekkan Dennou Club 147 / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin / games / greversi / grevvs.lzh / src / think.s < prev    next >
Text File  |  2000-02-04  |  53KB  |  2,181 lines

  1. ;----------------------------------------------------------------
  2. ;    greversi.x v0.14 (2000.02.04) by M.Kamada
  3. ;    think.s 盤操作・思考ルーチン
  4. ;----------------------------------------------------------------
  5.  
  6.     .include    doscall.mac
  7.  
  8.     .include    const.equ
  9.  
  10. ;----------------------------------------------------------------
  11. ;α-β法
  12. ;
  13. ;    相手の番(min)        →β=1
  14. ;
  15. ;    自分の番(max)     α=1        α>=3>=β→βカット
  16. ;
  17. ;    自分の評価値    -3 1 -7        3 (-1 2)
  18.  
  19. ;----------------------------------------------------------------
  20. ;石差を計算する
  21. ;<d6.b:自分の石
  22. ;<d7.b:相手の石
  23. ;>d0.w:石差(自分の石の数-相手の石の数)
  24. ;>z-flag:eq=引き分け
  25. ;>n-flag:mi=自分が相手に負けている
  26.     .text
  27.     .align    4,$2048
  28. get_sekisa::
  29.     movem.l    d1-d2/a0,-(sp)
  30.     moveq.l    #0,d0
  31.     lea.l    ban+P11,a0
  32.     moveq.l    #P88-P11,d1
  33. 1:    move.b    (a0)+,d2
  34.     ble    3f
  35.     cmp.b    d6,d2
  36.     bne    2f
  37.     addq.w    #1,d0
  38.     dbra    d1,1b
  39.     bra    4f
  40. 2:    subq.w    #1,d0
  41. 3:    dbra    d1,1b
  42. 4:    tst.w    d0
  43.     movem.l    (sp)+,d1-d2/a0
  44.     rts
  45.  
  46. ;----------------------------------------------------------------
  47. ;盤を初期化する
  48.     .text
  49.     .align    4,$2048
  50. init_think::
  51.     movem.l    a0-a1,-(sp)
  52.     lea.l    ban,a0
  53.     lea.l    sban,a1
  54.   .rept (BAN_LEN+3)/4
  55.     move.l    (a1)+,(a0)+
  56.   .endm
  57.     movem.l    (sp)+,a0-a1
  58.     rts
  59.  
  60. ;----------------------------------------------------------------
  61. ;思考ルーチン
  62. ;    自分の石を置ける位置が1箇所以上あるときだけ呼び出すこと
  63. ;<d0.w:レベル(1~5)
  64. ;<d6.b:自分の石
  65. ;<d7.b:相手の石
  66. ;>d0.l:置く位置(盤の先頭からのオフセット)
  67.     .text
  68.     .align    4,$2048
  69. think::
  70.     movem.l    d1-d7/a0-a6,-(sp)
  71. ;レベル設定
  72.     lea.l    (level_table,pc),a0
  73.     subq.w    #1,d0
  74.     lsl.w    #3,d0
  75.     adda.w    d0,a0
  76.     move.w    (a0)+,depth_level
  77.     move.w    (a0)+,hisshou_level
  78.     move.w    (a0)+,kanzen_level
  79. ;空いているマスを数える
  80.     moveq.l    #0,d0
  81.     lea.l    ban+P11,a0
  82.     moveq.l    #P88-P11,d1
  83. 1:    tst.b    (a0)+
  84.     bne    @f
  85.     addq.w    #1,d0
  86. @@:    dbra    d1,1b
  87.     move.w    d0,aki_count
  88. ;終盤の読み切り
  89.     bsr    yomikiri
  90.     bne    99f
  91. ;定石探索
  92.     bsr    joseki
  93.     bne    99f            ;定石による手が見つかった
  94. ;自分が置ける場所のリストを作る
  95.     bsr    list_ban
  96.     lea.l    eval_list,a2        ;リストの先頭(評価値が大きい順に並べる)
  97.     movea.l    a2,a3
  98.     clr.l    (a3)+            ;置く位置(番兵なので0)
  99.     clr.l    (a3)+            ;次のセルへのポインタ(番兵なので無効)
  100.     move.l    #$80000000,(a3)+    ;評価値(番兵なので最小値)
  101.     move.l    (a1)+,d0        ;置く位置
  102. 1:    movea.l    d0,a0            ;置く位置
  103.     move.l    a0,(a3)            ;置く位置
  104.     bsr    put_record_one
  105.     exg.l    d6,d7
  106.     bsr    eval            ;評価してみる
  107.     exg.l    d6,d7
  108.     neg.l    d0
  109.     move.l    d0,(8,a3)        ;評価値
  110.     movea.l    a2,a0            ;リストの先頭
  111.     bra    16f
  112. 15:    movea.l    a0,a4            ;直前のセルへのポインタ
  113.     movea.l    (4,a0),a0
  114. 16:    cmp.l    (8,a0),d0        ;評価値を比較
  115.     ble    15b
  116.     move.l    a0,(4,a3)        ;次のセルへのポインタ
  117.     cmpa.l    a2,a0
  118.     beq    17f
  119.     move.l    a3,(4,a4)        ;直前のセルの次のセルへのポインタを更新する
  120.     bra    18f
  121. 17:    movea.l    a3,a2            ;リストの先頭を更新する
  122. 18:    lea.l    (12,a3),a3        ;次の空きセル
  123.     bsr    tup_record_one
  124.     move.l    (a1)+,d0        ;置く位置
  125.     bne    1b
  126. ;ミニマックス法+α-β法
  127.     moveq.l    #0,d3            ;最大の評価値を得た手の数
  128.     move.w    depth_level,d4
  129.     subq.w    #1,d4            ;先読みの深さ
  130.     movea.l    #$80000000,a3        ;α
  131.     movea.l    #$7FFFFFFF,a4        ;β
  132.     movea.l    a2,a1            ;置く位置のリストの先頭
  133.     move.l    (a1)+,d0        ;置く位置
  134. 1:    movea.l    d0,a0            ;置く位置
  135.     bsr    put_record_one
  136.     exg.l    d6,d7
  137. ;<d6.b:相手の石
  138. ;<d7.b:自分の石
  139.     bsr    eval_min        ;相手の手番で自分の評価値の最小値を求める
  140.     exg.l    d6,d7
  141.     cmp.l    a3,d0
  142.     blt    2f
  143.     bgt    3f
  144. ;最大の評価値が同一
  145.     addq.w    #1,d3            ;最大の評価値を得た手の数
  146.     bsr    myrand
  147.     and.l    #$0000FFFF,d0
  148.     divu.w    d3,d0
  149.     swap.w    d0
  150.     tst.w    d0
  151.     beq    4f            ;n番目の手は1/nの確率で採用される
  152.     bra    2f
  153. 3:    moveq.l    #1,d3            ;最大の評価値を得た手の数
  154.     movea.l    d0,a3            ;αを更新
  155. 4:    movea.l    a0,a2            ;相手の手番で自分の評価値の最小値が最大になる手
  156. 2:    bsr    tup_record_one
  157.     movea.l    (a1)+,a1        ;次のセルへのポインタ(最後に番兵が出てくる)
  158.     move.l    (a1)+,d0        ;置く位置(番兵のセルは0)
  159.     bne    1b
  160.     move.l    a2,d0            ;相手の手番で自分の評価値の最小値が最大になる手
  161.     sub.l    #ban,d0
  162. 99:    movem.l    (sp)+,d1-d7/a0-a6
  163.     rts
  164.  
  165. level_table:    .dc.w    2,8,6,0
  166.         .dc.w    3,10,8,0
  167.         .dc.w    4,12,10,0
  168.         .dc.w    5,14,12,0
  169.         .dc.w    6,16,14,0
  170.  
  171.     .bss
  172.     .even
  173. depth_level:    .ds.w    1
  174. hisshou_level:    .ds.w    1
  175. kanzen_level:    .ds.w    1
  176. aki_count:    .ds.w    1
  177.     .align    4
  178. eval_list:    .ds.l    3*(60+1)
  179.  
  180. ;----------------------------------------------------------------
  181. ;自分の手番で自分の評価値の最大値を求める
  182. ;<d4.w:先読みの深さ
  183. ;<d6.b:自分の石
  184. ;<d7.b:相手の石
  185. ;<a3.l:α
  186. ;<a4.l:β
  187. ;>d0.l:評価値
  188. ;?d1-d2
  189.     .text
  190.     .align    4,$2048
  191. eval_max:
  192.     tst.w    d4
  193.     beq    eval
  194.     movem.l    d3-d4/a0-a1/a3/a5-a6,-(sp)
  195.     bsr    list_ban        ;自分が置ける位置のリストを作る
  196.     beq    5f            ;どこにも置けない(パスまたは終局)
  197.     subq.w    #1,d4            ;先読みの深さ
  198.     move.l    (a1)+,d0
  199. 1:    movea.l    d0,a0
  200.     bsr    put_record_one
  201.     exg.l    d6,d7
  202. ;<d6.b:相手の石
  203. ;<d7.b:自分の石
  204.     bsr    eval_min        ;相手の手番で自分の評価値の最小値を求める
  205.     exg.l    d6,d7
  206.     cmp.l    a3,d0
  207.     ble    @f
  208.     movea.l    d0,a3            ;αを更新
  209. @@:    bsr    tup_record_one
  210.     cmpa.l    a4,a3
  211.     bge    7f            ;α>=βなのでβカット
  212.     move.l    (a1)+,d0
  213.     bne    1b
  214. 98:    move.l    a3,d0            ;αを返す
  215. 99:    movem.l    (sp)+,d3-d4/a0-a1/a3/a5-a6
  216.     rts
  217.  
  218. ;どこにも置けない(パスまたは終局)
  219. 5:    exg.l    d6,d7
  220. ;<d6.b:相手の石
  221. ;<d7.b:自分の石
  222.     bsr    count_ban
  223.     beq    6f            ;相手も置けないので終局
  224.     bsr    eval_min        ;相手の手番で自分の評価値の最小値を求める
  225.     exg.l    d6,d7
  226. ;<d6.b:自分の石
  227. ;<d7.b:相手の石
  228.     bra    99b
  229.  
  230. ;相手も置けないので終局
  231. 6:    exg.l    d6,d7
  232. ;<d6.b:自分の石
  233. ;<d7.b:相手の石
  234.     bsr    get_sekisa
  235.     asl.w    #8,d0            ;石差×256
  236.     ext.l    d0
  237.     bra    99b
  238.  
  239. ;α>=βなのでβカット
  240. ;親のαを返してはならない(評価値が同じだと選択されてしまうことがある)
  241. 7:    move.l    #$3FFFFFFF,d0        ;絶対に選択されない
  242.     bra    99b
  243.  
  244. ;----------------------------------------------------------------
  245. ;相手の手番で自分の評価値の最小値を求める
  246. ;<d4.w:先読みの深さ
  247. ;<d6.b:相手の石
  248. ;<d7.b:自分の石
  249. ;<a3.l:α
  250. ;<a4.l:β
  251. ;>d0.l:評価値
  252. ;?d1-d2
  253.     .text
  254.     .align    4,$2048
  255. @@:    bsr    eval
  256.     neg.l    d0
  257.     rts
  258.     .align    4,$2048
  259. eval_min:
  260.     tst.w    d4
  261.     beq    @b
  262.     movem.l    d3-d4/a0-a1/a4/a5-a6,-(sp)
  263.     bsr    list_ban        ;相手が置ける位置のリストを作る
  264.     beq    5f            ;どこにも置けない(パスまたは終局)
  265.     subq.w    #1,d4            ;先読みの深さ
  266.     move.l    (a1)+,d0
  267. 1:    movea.l    d0,a0
  268.     bsr    put_record_one
  269.     exg.l    d6,d7
  270. ;<d6.b:自分の石
  271. ;<d7.b:相手の石
  272.     bsr    eval_max        ;自分の手番で自分の評価値の最大値を求める
  273.     exg.l    d6,d7
  274.     cmp.l    a4,d0
  275.     bge    @f
  276.     movea.l    d0,a4            ;βを更新
  277. @@:    bsr    tup_record_one
  278.     cmpa.l    a3,a4
  279.     ble    7f            ;β<=αなのでαカット
  280.     move.l    (a1)+,d0
  281.     bne    1b
  282. 98:    move.l    a4,d0            ;βを返す
  283. 99:    movem.l    (sp)+,d3-d4/a0-a1/a4/a5-a6
  284.     rts
  285.  
  286. ;どこにも置けない(パスまたは終局)
  287. 5:    exg.l    d6,d7
  288. ;<d6.b:自分の石
  289. ;<d7.b:相手の石
  290.     bsr    count_ban
  291.     beq    6f            ;自分も置けないので終局
  292.     bsr    eval_max        ;自分の手番で自分の評価値の最大値を求める
  293.     exg.l    d6,d7
  294. ;<d6.b:相手の石
  295. ;<d7.b:自分の石
  296.     bra    99b
  297.  
  298. ;自分も置けないので終局
  299. 6:    bsr    get_sekisa
  300.     asl.w    #8,d0            ;石差×256
  301.     ext.l    d0
  302.     exg.l    d6,d7
  303. ;<d6.b:相手の石
  304. ;<d7.b:自分の石
  305.     bra    99b
  306.  
  307. ;β<=αなのでαカット
  308. ;親のβを返してはならない(評価値が同じだと選択されてしまうことがある)
  309. 7:    move.l    #$C0000000,d0        ;絶対に選択されない
  310.     bra    99b
  311.  
  312. ;----------------------------------------------------------------
  313. ;評価関数
  314. ;<d6.b:自分の石
  315. ;>d0.l:評価値
  316. ;?d1-d2
  317.     .text
  318.     .align    4,$2048
  319. eval:
  320.     movem.l    d3-d4/a0-a2,-(sp)
  321. ;スキャンマップを初期化する
  322.     lea.l    map,a1
  323.     moveq.l    #0,d0
  324.     .rept (BAN_LEN+3)/4
  325.     move.l    d0,(a1)+
  326.     .endm
  327. ;スキャン(右)
  328. ;        1  2  3  4  5  6  7  8
  329. ;      ┏━┯━┯━┯━┯━┯━┯━┯━┓
  330. ;    1┃●─────────────→┃
  331. ;      ┠─┼─┼─┼─┼─┼─┼─┼─┨
  332. ;    2┃●─────────────→┃
  333. ;      ┠─┼─┼─┼─┼─┼─┼─┼─┨
  334. ;    3┃●─────────────→┃
  335. ;      ┠─┼─┼─┼─┼─┼─┼─┼─┨
  336. ;    4┃●─────────────→┃
  337. ;      ┠─┼─┼─┼─┼─┼─┼─┼─┨
  338. ;    5┃●─────────────→┃
  339. ;      ┠─┼─┼─┼─┼─┼─┼─┼─┨
  340. ;    6┃●─────────────→┃
  341. ;      ┠─┼─┼─┼─┼─┼─┼─┼─┨
  342. ;    7┃●─────────────→┃
  343. ;      ┠─┼─┼─┼─┼─┼─┼─┼─┨
  344. ;    8┃●─────────────→┃
  345. ;      ┗━┷━┷━┷━┷━┷━┷━┷━┛
  346.     moveq.l    #V5,d1
  347.     lea.l    ban+P11,a0
  348.     bsr    scan
  349.     lea.l    ban+P12,a0
  350.     bsr    scan
  351.     lea.l    ban+P13,a0
  352.     bsr    scan
  353.     lea.l    ban+P14,a0
  354.     bsr    scan
  355.     lea.l    ban+P15,a0
  356.     bsr    scan
  357.     lea.l    ban+P16,a0
  358.     bsr    scan
  359.     lea.l    ban+P17,a0
  360.     bsr    scan
  361.     lea.l    ban+P18,a0
  362.     bsr    scan
  363. ;スキャン(左下)
  364. ;        1  2  3  4  5  6  7  8
  365. ;      ┏━┯━┯━┯━┯━┯━┯━┯━┓
  366. ;    1┃  │  │●│●│●│●│●│●┃
  367. ;      ┠─┼─/─/─/─/─/─/─┨
  368. ;    2┃  │/│/│/│/│/│/│●┃
  369. ;      ┠─/─/─/─/─/─/─/─┨
  370. ;    3┃/│/│/│/│/│/│/│●┃
  371. ;      ┠─/─/─/─/─/─/─/─┨
  372. ;    4┃/│/│/│/│/│/│/│●┃
  373. ;      ┠─/─/─/─/─/─/─/─┨
  374. ;    5┃/│/│/│/│/│/│/│●┃
  375. ;      ┠─/─/─/─/─/─/─/─┨
  376. ;    6┃/│/│/│/│/│/│/│●┃
  377. ;      ┠─/─/─/─/─/─/─/─┨
  378. ;    7┃/│/│/│/│/│/│/│  ┃
  379. ;      ┠─/─/─/─/─/─/─┼─┨
  380. ;    8┃/│/│/│/│/│/│  │  ┃
  381. ;      ┗━┷━┷━┷━┷━┷━┷━┷━┛
  382.     moveq.l    #V6,d1
  383.     lea.l    ban+P31,a0
  384.     bsr    scan
  385.     lea.l    ban+P41,a0
  386.     bsr    scan
  387.     lea.l    ban+P51,a0
  388.     bsr    scan
  389.     lea.l    ban+P61,a0
  390.     bsr    scan
  391.     lea.l    ban+P71,a0
  392.     bsr    scan
  393.     lea.l    ban+P81,a0
  394.     bsr    scan
  395.     lea.l    ban+P82,a0
  396.     bsr    scan
  397.     lea.l    ban+P83,a0
  398.     bsr    scan
  399.     lea.l    ban+P84,a0
  400.     bsr    scan
  401.     lea.l    ban+P85,a0
  402.     bsr    scan
  403.     lea.l    ban+P86,a0
  404.     bsr    scan
  405. ;スキャン(下)
  406. ;        1  2  3  4  5  6  7  8
  407. ;      ┏━┯━┯━┯━┯━┯━┯━┯━┓
  408. ;    1┃●│●│●│●│●│●│●│●┃
  409. ;      ┠│┼│┼│┼│┼│┼│┼│┼│┨
  410. ;    2┃│││││││││││││││┃
  411. ;      ┠│┼│┼│┼│┼│┼│┼│┼│┨
  412. ;    3┃│││││││││││││││┃
  413. ;      ┠│┼│┼│┼│┼│┼│┼│┼│┨
  414. ;    4┃│││││││││││││││┃
  415. ;      ┠│┼│┼│┼│┼│┼│┼│┼│┨
  416. ;    5┃│││││││││││││││┃
  417. ;      ┠│┼│┼│┼│┼│┼│┼│┼│┨
  418. ;    6┃│││││││││││││││┃
  419. ;      ┠│┼│┼│┼│┼│┼│┼│┼│┨
  420. ;    7┃│││││││││││││││┃
  421. ;      ┠│┼│┼│┼│┼│┼│┼│┼│┨
  422. ;    8┃↓│↓│↓│↓│↓│↓│↓│↓┃
  423. ;      ┗━┷━┷━┷━┷━┷━┷━┷━┛
  424.     moveq.l    #V7,d1
  425.     lea.l    ban+P11,a0
  426.     bsr    scan
  427.     lea.l    ban+P21,a0
  428.     bsr    scan
  429.     lea.l    ban+P31,a0
  430.     bsr    scan
  431.     lea.l    ban+P41,a0
  432.     bsr    scan
  433.     lea.l    ban+P51,a0
  434.     bsr    scan
  435.     lea.l    ban+P61,a0
  436.     bsr    scan
  437.     lea.l    ban+P71,a0
  438.     bsr    scan
  439.     lea.l    ban+P81,a0
  440.     bsr    scan
  441. ;スキャン(右下)
  442. ;        1  2  3  4  5  6  7  8
  443. ;      ┏━┯━┯━┯━┯━┯━┯━┯━┓
  444. ;    1┃●│●│●│●│●│●│  │  ┃
  445. ;      ┠─\─\─\─\─\─\─┼─┨
  446. ;    2┃●│\│\│\│\│\│\│  ┃
  447. ;      ┠─\─\─\─\─\─\─\─┨
  448. ;    3┃●│\│\│\│\│\│\│\┃
  449. ;      ┠─\─\─\─\─\─\─\─┨
  450. ;    4┃●│\│\│\│\│\│\│\┃
  451. ;      ┠─\─\─\─\─\─\─\─┨
  452. ;    5┃●│\│\│\│\│\│\│\┃
  453. ;      ┠─\─\─\─\─\─\─\─┨
  454. ;    6┃●│\│\│\│\│\│\│\┃
  455. ;      ┠─\─\─\─\─\─\─\─┨
  456. ;    7┃  │\│\│\│\│\│\│\┃
  457. ;      ┠─┼─\─\─\─\─\─\─┨
  458. ;    8┃  │  │\│\│\│\│\│\┃
  459. ;      ┗━┷━┷━┷━┷━┷━┷━┷━┛
  460.     moveq.l    #V8,d1
  461.     lea.l    ban+P11,a0
  462.     bsr    scan
  463.     lea.l    ban+P21,a0
  464.     bsr    scan
  465.     lea.l    ban+P31,a0
  466.     bsr    scan
  467.     lea.l    ban+P41,a0
  468.     bsr    scan
  469.     lea.l    ban+P51,a0
  470.     bsr    scan
  471.     lea.l    ban+P61,a0
  472.     bsr    scan
  473.     lea.l    ban+P12,a0
  474.     bsr    scan
  475.     lea.l    ban+P13,a0
  476.     bsr    scan
  477.     lea.l    ban+P14,a0
  478.     bsr    scan
  479.     lea.l    ban+P15,a0
  480.     bsr    scan
  481.     lea.l    ban+P16,a0
  482.     bsr    scan
  483. ;隅から辺へのスキャン
  484. ;        1  2  3  4  5  6  7  8
  485. ;      ┏━┯━┯━┯━┯━┯━┯━┯━┓
  486. ;    1┃●─────────────→┃
  487. ;      ┠│\─┼─┼─┼─┼─┼─┼─┨
  488. ;    2┃││\│  │  │  │  │  │  ┃
  489. ;      ┠│┼─┼─┼─┼─┼─┼─┼─┨
  490. ;    3┃││  │  │  │  │  │  │  ┃
  491. ;      ┠│┼─┼─┼─┼─┼─┼─┼─┨
  492. ;    4┃││  │  │  │  │  │  │  ┃
  493. ;      ┠│┼─┼─┼─┼─┼─┼─┼─┨
  494. ;    5┃││  │  │  │  │  │  │  ┃
  495. ;      ┠│┼─┼─┼─┼─┼─┼─┼─┨
  496. ;    6┃││  │  │  │  │  │  │  ┃
  497. ;      ┠│┼─┼─┼─┼─┼─┼─┼─┨
  498. ;    7┃││  │  │  │  │  │  │  ┃
  499. ;      ┠│┼─┼─┼─┼─┼─┼─┼─┨
  500. ;    8┃↓│  │  │  │  │  │  │  ┃
  501. ;      ┗━┷━┷━┷━┷━┷━┷━┷━┛
  502.     lea.l    ban+P11,a0
  503.     moveq.l    #V5,d0
  504.     moveq.l    #V7,d1
  505.     bsr    scan_edge
  506. ;        1  2  3  4  5  6  7  8
  507. ;      ┏━┯━┯━┯━┯━┯━┯━┯━┓
  508. ;    1┃←─────────────●┃
  509. ;      ┠─┼─┼─┼─┼─┼─┼─/│┨
  510. ;    2┃  │  │  │  │  │  │/││┃
  511. ;      ┠─┼─┼─┼─┼─┼─┼─┼│┨
  512. ;    3┃  │  │  │  │  │  │  ││┃
  513. ;      ┠─┼─┼─┼─┼─┼─┼─┼│┨
  514. ;    4┃  │  │  │  │  │  │  ││┃
  515. ;      ┠─┼─┼─┼─┼─┼─┼─┼│┨
  516. ;    5┃  │  │  │  │  │  │  ││┃
  517. ;      ┠─┼─┼─┼─┼─┼─┼─┼│┨
  518. ;    6┃  │  │  │  │  │  │  ││┃
  519. ;      ┠─┼─┼─┼─┼─┼─┼─┼│┨
  520. ;    7┃  │  │  │  │  │  │  ││┃
  521. ;      ┠─┼─┼─┼─┼─┼─┼─┼│┨
  522. ;    8┃  │  │  │  │  │  │  │↓┃
  523. ;      ┗━┷━┷━┷━┷━┷━┷━┷━┛
  524.     lea.l    ban+P81,a0
  525.     moveq.l    #V4,d0
  526.     moveq.l    #V7,d1
  527.     bsr    scan_edge
  528. ;        1  2  3  4  5  6  7  8
  529. ;      ┏━┯━┯━┯━┯━┯━┯━┯━┓
  530. ;    1┃↑│  │  │  │  │  │  │  ┃
  531. ;      ┠│┼─┼─┼─┼─┼─┼─┼─┨
  532. ;    2┃││  │  │  │  │  │  │  ┃
  533. ;      ┠│┼─┼─┼─┼─┼─┼─┼─┨
  534. ;    3┃││  │  │  │  │  │  │  ┃
  535. ;      ┠│┼─┼─┼─┼─┼─┼─┼─┨
  536. ;    4┃││  │  │  │  │  │  │  ┃
  537. ;      ┠│┼─┼─┼─┼─┼─┼─┼─┨
  538. ;    5┃││  │  │  │  │  │  │  ┃
  539. ;      ┠│┼─┼─┼─┼─┼─┼─┼─┨
  540. ;    6┃││  │  │  │  │  │  │  ┃
  541. ;      ┠│┼─┼─┼─┼─┼─┼─┼─┨
  542. ;    7┃││/│  │  │  │  │  │  ┃
  543. ;      ┠│/─┼─┼─┼─┼─┼─┼─┨
  544. ;    8┃●─────────────→┃
  545. ;      ┗━┷━┷━┷━┷━┷━┷━┷━┛
  546.     lea.l    ban+P18,a0
  547.     moveq.l    #V5,d0
  548.     moveq.l    #V2,d1
  549.     bsr    scan_edge
  550. ;        1  2  3  4  5  6  7  8
  551. ;      ┏━┯━┯━┯━┯━┯━┯━┯━┓
  552. ;    1┃  │  │  │  │  │  │  │↑┃
  553. ;      ┠─┼─┼─┼─┼─┼─┼─┼│┨
  554. ;    2┃  │  │  │  │  │  │  ││┃
  555. ;      ┠─┼─┼─┼─┼─┼─┼─┼│┨
  556. ;    3┃  │  │  │  │  │  │  ││┃
  557. ;      ┠─┼─┼─┼─┼─┼─┼─┼│┨
  558. ;    4┃  │  │  │  │  │  │  ││┃
  559. ;      ┠─┼─┼─┼─┼─┼─┼─┼│┨
  560. ;    5┃  │  │  │  │  │  │  ││┃
  561. ;      ┠─┼─┼─┼─┼─┼─┼─┼│┨
  562. ;    6┃  │  │  │  │  │  │  ││┃
  563. ;      ┠─┼─┼─┼─┼─┼─┼─┼│┨
  564. ;    7┃  │  │  │  │  │  │\││┃
  565. ;      ┠─┼─┼─┼─┼─┼─┼─\│┨
  566. ;    8┃←─────────────●┃
  567. ;      ┗━┷━┷━┷━┷━┷━┷━┷━┛
  568.     lea.l    ban+P88,a0
  569.     moveq.l    #V4,d0
  570.     moveq.l    #V2,d1
  571.     bsr    scan_edge
  572. ;スキャンマップをもとに評価を行う
  573.     moveq.l    #0,d4            ;最下位バイト以外を0に固定
  574.     lea.l    ban+P11,a0
  575.     suba.l    a2,a2            ;評価値
  576.     moveq.l    #P88-P11,d1
  577. 10:    move.b    (a0)+,d0
  578.     bmi    50f            ;壁
  579.     bne    30f            ;石がある
  580. ;空き
  581.     moveq.l    #MAP_ICANPUT|MAP_YOUCANPUT,d3
  582.     and.b    (map-ban-1,a0),d3
  583.     beq    50f            ;空きでどちらも置けない
  584. ;空きで少なくともどちらかが置ける
  585.     move.b    (yoyuu-ban-1,a0),d4
  586.     subq.b    #MAP_ICANPUT,d3
  587.     bne    @f
  588. ;空きで自分だけが置ける
  589.     adda.w    d4,a2
  590.     bra    50f
  591. @@:    subq.b    #MAP_YOUCANPUT-MAP_ICANPUT,d3
  592.     bne    50f            ;空きで自分と相手の両方が置ける
  593. ;空きで相手だけが置ける
  594.     suba.w    d4,a2
  595.     bra    50f
  596.  
  597. ;石がある
  598. 30:    cmp.b    d6,d0
  599.     bne    40f            ;相手の石がある
  600. ;自分の石がある
  601.     moveq.l    #MAP_YOUCANGET,d3
  602.     and.b    (map-ban-1,a0),d3
  603.     bne    @f            ;自分の石があって相手がひっくり返せる
  604. ;自分の石があって相手がひっくり返せない→自分の確定石
  605.     move.b    (kakutei-ban-1,a0),d4
  606.     adda.w    d4,a2
  607.     bra    50f
  608. ;自分の石があって相手がひっくり返せる
  609. @@:    move.b    (kiken-ban-1,a0),d4
  610.     suba.w    d4,a2
  611.     bra    50f
  612.  
  613. ;相手の石がある
  614. 40:    moveq.l    #MAP_ICANGET,d3
  615.     and.b    (map-ban-1,a0),d3
  616.     bne    @f            ;相手の石があって自分がひっくり返せる
  617. ;相手の石があって自分がひっくり返せない→相手の確定石
  618.     move.b    (kakutei-ban-1,a0),d4
  619.     suba.w    d4,a2
  620.     bra    50f
  621. ;相手の石があって自分がひっくり返せる
  622. @@:    move.b    (kiken-ban-1,a0),d4
  623.     adda.w    d4,a2
  624.     bra    50f
  625.  
  626. 50:
  627.     dbra    d1,10b
  628.     move.l    a2,d0            ;評価値
  629.     movem.l    (sp)+,d3-d4/a0-a2
  630.     rts
  631.  
  632. ;----------------------------------------------------------------
  633. ;ラインスキャンを行う
  634. ;    マスが3個以上あるラインを指定すること
  635. ;<d1.w:ベクタ
  636. ;<d6.b:自分の石
  637. ;<a0.l:開始位置(ban)
  638. ;?a1-a2
  639.     .text
  640.     .align    4,$2048
  641. scan:
  642.     move.b    (a0),d0
  643.     bne    19f            ;石がある
  644. ;空き
  645. 10:    movea.l    a0,a1
  646.     adda.w    d1,a0
  647.     move.b    (a0),d0
  648.     bmi    99f            ;空き→壁
  649.     beq    10b            ;空き→空き
  650.     cmp.b    d6,d0
  651.     bne    12f            ;空き→相手の石
  652. ;空き→自分の石
  653. 11:    movea.l    a0,a2
  654.     adda.w    d1,a0
  655.     move.b    (a0),d0
  656.     bmi    99f            ;空き→自分の石→壁
  657.     beq    10b            ;空き→自分の石→空き
  658.     cmp.b    d6,d0
  659.     beq    11b            ;空き→自分の石→自分の石
  660. ;空き→自分の石→相手の石
  661.     ori.b    #MAP_YOUCANPUT,(map-ban,a1)
  662.     adda.w    d1,a1
  663. @@:    ori.b    #MAP_YOUCANGET,(map-ban,a1)
  664.     adda.w    d1,a1
  665.     cmpa.l    a0,a1
  666.     bne    @b
  667.     movea.l    a2,a1
  668.     bra    21f            ;自分の石→相手の石
  669.  
  670. ;空き→相手の石
  671. 12:    movea.l    a0,a2
  672.     adda.w    d1,a0
  673.     move.b    (a0),d0
  674.     bmi    99f            ;空き→相手の石→壁
  675.     beq    10b            ;空き→相手の石→空き
  676.     cmp.b    d6,d0
  677.     bne    12b            ;空き→相手の石→相手の石
  678. ;空き→相手の石→自分の石
  679.     ori.b    #MAP_ICANPUT,(map-ban,a1)
  680.     adda.w    d1,a1
  681. @@:    ori.b    #MAP_ICANGET,(map-ban,a1)
  682.     adda.w    d1,a1
  683.     cmpa.l    a0,a1
  684.     bne    @b
  685.     movea.l    a2,a1
  686.     bra    31f            ;相手の石→自分の石
  687.  
  688. ;石がある
  689. 19:    cmp.b    d6,d0
  690.     bne    30f            ;相手の石
  691. ;自分の石
  692. 20:    movea.l    a0,a1
  693.     adda.w    d1,a0
  694.     move.b    (a0),d0
  695.     bmi    99f            ;自分の石→壁
  696.     beq    10b            ;自分の石→空き
  697.     cmp.b    d6,d0
  698.     beq    20b            ;自分の石→自分の石
  699. ;自分の石→相手の石
  700. 21:    movea.l    a0,a2
  701.     adda.w    d1,a0
  702.     move.b    (a0),d0
  703.     bmi    99f            ;自分の石→相手の石→壁
  704.     beq    22f            ;自分の石→相手の石→空き
  705.     cmp.b    d6,d0
  706.     bne    21b            ;自分の石→相手の石→相手の石
  707. ;自分の石→相手の石→自分の石
  708.     movea.l    a2,a1
  709.     bra    31f            ;相手の石→自分の石
  710.  
  711. ;自分の石→相手の石→空き
  712. 22:    adda.w    d1,a1
  713. @@:    ori.b    #MAP_ICANGET,(map-ban,a1)
  714.     adda.w    d1,a1
  715.     cmpa.l    a0,a1
  716.     bne    @b
  717.     ori.b    #MAP_ICANPUT,(map-ban,a0)
  718.     bra    10b
  719.  
  720. ;相手の石
  721. 30:    movea.l    a0,a1
  722.     adda.w    d1,a0
  723.     move.b    (a0),d0
  724.     bmi    99f            ;相手の石→壁
  725.     beq    10b            ;相手の石→空き
  726.     cmp.b    d6,d0
  727.     bne    30b            ;相手の石→相手の石
  728. ;相手の石→自分の石
  729. 31:    movea.l    a0,a2
  730.     adda.w    d1,a0
  731.     move.b    (a0),d0
  732.     bmi    99f            ;相手の石→自分の石→壁
  733.     beq    32f            ;相手の石→自分の石→空き
  734.     cmp.b    d6,d0
  735.     beq    31b            ;相手の石→自分の石→自分の石
  736. ;相手の石→自分の石→相手の石
  737.     movea.l    a2,a1
  738.     bra    21b            ;自分の石→相手の石
  739.  
  740. ;相手の石→自分の石→空き
  741. 32:    adda.w    d1,a1
  742. @@:    ori.b    #MAP_YOUCANGET,(map-ban,a1)
  743.     adda.w    d1,a1
  744.     cmpa.l    a0,a1
  745.     bne    @b
  746.     ori.b    #MAP_YOUCANPUT,(map-ban,a0)
  747.     bra    10b
  748.  
  749. 99:    rts
  750.  
  751. ;----------------------------------------------------------------
  752. ;隅から辺へのスキャン
  753. ;    辺は両方の隅からスキャンされるので,ここでは片方向だけスキャンすればよい
  754. ;    星もチェックする
  755. ;<a0.l:隅の位置
  756. ;<d0.w:辺のベクトル
  757. ;<d1.w:辺のベクトル
  758. ;<d6.b:自分の石
  759. ;<d7.b:相手の石
  760. ;?d2-d3/a1
  761.     .text
  762.     .align    4,$2048
  763. scan_edge:
  764.     tst.b    (a0)
  765.     bne    99f            ;隅が空いていなければスキップ
  766.  
  767. ;隅が空いていて星に石があるとき,星と隅をマークする
  768.     move.w    d0,d2
  769.     add.w    d1,d2            ;隅から星へのベクトル
  770.     move.b    (a0,d2.w),d3        ;星
  771.     beq    2f            ;星に石がない
  772.     cmp.b    d6,d3
  773.     bne    1f            ;隅が空いていて星に相手の石がある
  774. ;隅が空いていて星に自分の石がある
  775.     ori.b    #MAP_YOUCANGET,(map-ban,a0,d2.w)
  776.     ori.b    #MAP_YOUCANPUT,(map-ban,a0)
  777.     bra    2f
  778. ;隅が空いていて星に相手の石がある
  779. 1:    ori.b    #MAP_ICANGET,(map-ban,a0,d2.w)
  780.     ori.b    #MAP_ICANPUT,(map-ban,a0)
  781. 2:
  782.  
  783. ;隅が空いていて隣に石が5個まで連続してあるとき,その石と隅をマークする
  784.     move.b    (a0,d0.w),d2        ;隣
  785.     beq    30f            ;隣に石がない
  786. ;隅が空いていて隣に石がある
  787.     cmp.b    d6,d2
  788.     bne    20f            ;隅が空いていて隣に相手の石がある
  789. ;隅が空いていて隣に自分の石がある
  790.     moveq.l    #MAP_YOUCANGET,d2
  791.     movea.l    a0,a1
  792.     adda.w    d0,a1
  793.     adda.w    d0,a1
  794.     cmp.b    (a1),d6
  795.     bne    11f            ;隅が空いていて隣に自分の石が1個だけある
  796.     adda.w    d0,a1
  797.     cmp.b    (a1),d6
  798.     bne    12f            ;隅が空いていて隣に自分の石が2個だけある
  799.     adda.w    d0,a1
  800.     cmp.b    (a1),d6
  801.     bne    13f            ;隅が空いていて隣に自分の石が3個だけある
  802.     adda.w    d0,a1
  803.     cmp.b    (a1),d6
  804.     bne    14f            ;隅が空いていて隣に自分の石が4個だけある
  805.     adda.w    d0,a1
  806.     cmp.b    (a1),d6
  807.     beq    30f            ;隅が空いていて隣に自分の石が6個以上ある
  808. ;隅が空いていて隣に自分の石が5個だけある
  809.     suba.w    d0,a1
  810.     cmp.b    (a1,d1.w),d6
  811.     bne    30f            ;隅が空いていて隣に自分の石が5個だけあるが,
  812.                     ;ウイングにはなっていない
  813. ;隅が空いていて隣に自分の石が5個だけあって,ウイングになっている
  814. *****    or.b    d2,(map-ban,a1)
  815. ;隅が空いていて隣に自分の石が4個だけある
  816. 14:    suba.w    d0,a1
  817. *****    or.b    d2,(map-ban,a1)
  818. ;隅が空いていて隣に自分の石が3個だけある
  819. 13:    suba.w    d0,a1
  820. *****    or.b    d2,(map-ban,a1)
  821. ;隅が空いていて隣に自分の石が2個だけある
  822. 12:    suba.w    d0,a1
  823. *****    or.b    d2,(map-ban,a1)
  824. ;隅が空いていて隣に自分の石が1個だけある
  825. 11:    suba.w    d0,a1
  826.     or.b    d2,(map-ban,a1)
  827.     ori.b    #MAP_YOUCANPUT,(map-ban,a0)
  828.     bra    30f
  829.  
  830. ;隅が空いていて隣に相手の石がある
  831. 20:    moveq.l    #MAP_ICANGET,d2
  832.     movea.l    a0,a1
  833.     adda.w    d0,a1
  834.     adda.w    d0,a1
  835.     cmp.b    (a1),d7
  836.     bne    11f            ;隅が空いていて隣に相手の石が1個だけある
  837.     adda.w    d0,a1
  838.     cmp.b    (a1),d7
  839.     bne    12f            ;隅が空いていて隣に相手の石が2個だけある
  840.     adda.w    d0,a1
  841.     cmp.b    (a1),d7
  842.     bne    13f            ;隅が空いていて隣に相手の石が3個だけある
  843.     adda.w    d0,a1
  844.     cmp.b    (a1),d7
  845.     bne    14f            ;隅が空いていて隣に相手の石が4個だけある
  846.     adda.w    d0,a1
  847.     cmp.b    (a1),d7
  848.     beq    30f            ;隅が空いていて隣に相手の石が6個以上ある
  849. ;隅が空いていて隣に相手の石が5個だけある
  850.     suba.w    d0,a1
  851.     cmp.b    (a1,d1.w),d7
  852.     bne    30f            ;隅が空いていて隣に相手の石が5個だけあるが,
  853.                     ;ウイングにはなっていない
  854. ;隅が空いていて隣に相手の石が5個だけあって,ウイングになっている
  855. *****    or.b    d2,(map-ban,a1)
  856. ;隅が空いていて隣に相手の石が4個だけある
  857. 14:    suba.w    d0,a1
  858. *****    or.b    d2,(map-ban,a1)
  859. ;隅が空いていて隣に相手の石が3個だけある
  860. 13:    suba.w    d0,a1
  861. *****    or.b    d2,(map-ban,a1)
  862. ;隅が空いていて隣に相手の石が2個だけある
  863. 12:    suba.w    d0,a1
  864. *****    or.b    d2,(map-ban,a1)
  865. ;隅が空いていて隣に相手の石が1個だけある
  866. 11:    suba.w    d0,a1
  867.     or.b    d2,(map-ban,a1)
  868.     ori.b    #MAP_ICANPUT,(map-ban,a0)
  869. ;    bra    30f
  870.  
  871. 30:
  872.  
  873. ;隅が空いていて隣に石が5個まで連続してあるとき,その石と隅をマークする
  874.     move.b    (a0,d1.w),d2        ;隣
  875.     beq    30f            ;隣に石がない
  876. ;隅が空いていて隣に石がある
  877.     cmp.b    d6,d2
  878.     bne    20f            ;隅が空いていて隣に相手の石がある
  879. ;隅が空いていて隣に自分の石がある
  880.     moveq.l    #MAP_YOUCANGET,d2
  881.     movea.l    a0,a1
  882.     adda.w    d1,a1
  883.     adda.w    d1,a1
  884.     cmp.b    (a1),d6
  885.     bne    11f            ;隅が空いていて隣に自分の石が1個だけある
  886.     adda.w    d1,a1
  887.     cmp.b    (a1),d6
  888.     bne    12f            ;隅が空いていて隣に自分の石が2個だけある
  889.     adda.w    d1,a1
  890.     cmp.b    (a1),d6
  891.     bne    13f            ;隅が空いていて隣に自分の石が3個だけある
  892.     adda.w    d1,a1
  893.     cmp.b    (a1),d6
  894.     bne    14f            ;隅が空いていて隣に自分の石が4個だけある
  895.     adda.w    d1,a1
  896.     cmp.b    (a1),d6
  897.     beq    30f            ;隅が空いていて隣に自分の石が6個以上ある
  898. ;隅が空いていて隣に自分の石が5個だけある
  899.     suba.w    d1,a1
  900.     cmp.b    (a1,d0.w),d6
  901.     bne    30f            ;隅が空いていて隣に自分の石が5個だけあるが,
  902.                     ;ウイングにはなっていない
  903. ;隅が空いていて隣に自分の石が5個だけあって,ウイングになっている
  904. *****    or.b    d2,(map-ban,a1)
  905. ;隅が空いていて隣に自分の石が4個だけある
  906. 14:    suba.w    d1,a1
  907. *****    or.b    d2,(map-ban,a1)
  908. ;隅が空いていて隣に自分の石が3個だけある
  909. 13:    suba.w    d1,a1
  910. *****    or.b    d2,(map-ban,a1)
  911. ;隅が空いていて隣に自分の石が2個だけある
  912. 12:    suba.w    d1,a1
  913. *****    or.b    d2,(map-ban,a1)
  914. ;隅が空いていて隣に自分の石が1個だけある
  915. 11:    suba.w    d1,a1
  916.     or.b    d2,(map-ban,a1)
  917.     ori.b    #MAP_YOUCANPUT,(map-ban,a0)
  918.     bra    30f
  919.  
  920. ;隅が空いていて隣に相手の石がある
  921. 20:    moveq.l    #MAP_ICANGET,d2
  922.     movea.l    a0,a1
  923.     adda.w    d1,a1
  924.     adda.w    d1,a1
  925.     cmp.b    (a1),d7
  926.     bne    11f            ;隅が空いていて隣に相手の石が1個だけある
  927.     adda.w    d1,a1
  928.     cmp.b    (a1),d7
  929.     bne    12f            ;隅が空いていて隣に相手の石が2個だけある
  930.     adda.w    d1,a1
  931.     cmp.b    (a1),d7
  932.     bne    13f            ;隅が空いていて隣に相手の石が3個だけある
  933.     adda.w    d1,a1
  934.     cmp.b    (a1),d7
  935.     bne    14f            ;隅が空いていて隣に相手の石が4個だけある
  936.     adda.w    d1,a1
  937.     cmp.b    (a1),d7
  938.     beq    30f            ;隅が空いていて隣に相手の石が6個以上ある
  939. ;隅が空いていて隣に相手の石が5個だけある
  940.     suba.w    d1,a1
  941.     cmp.b    (a1,d0.w),d7
  942.     bne    30f            ;隅が空いていて隣に相手の石が5個だけあるが,
  943.                     ;ウイングにはなっていない
  944. ;隅が空いていて隣に相手の石が5個だけあって,ウイングになっている
  945. *****    or.b    d2,(map-ban,a1)
  946. ;隅が空いていて隣に相手の石が4個だけある
  947. 14:    suba.w    d1,a1
  948. *****    or.b    d2,(map-ban,a1)
  949. ;隅が空いていて隣に相手の石が3個だけある
  950. 13:    suba.w    d1,a1
  951. *****    or.b    d2,(map-ban,a1)
  952. ;隅が空いていて隣に相手の石が2個だけある
  953. 12:    suba.w    d1,a1
  954. *****    or.b    d2,(map-ban,a1)
  955. ;隅が空いていて隣に相手の石が1個だけある
  956. 11:    suba.w    d1,a1
  957.     or.b    d2,(map-ban,a1)
  958.     ori.b    #MAP_ICANPUT,(map-ban,a0)
  959. ;    bra    30f
  960.  
  961. 30:
  962.  
  963. 99:    rts
  964.  
  965. ;----------------------------------------------------------------
  966. ;自分の石を置ける位置のリストを作る
  967. ;<d6.b:自分の石
  968. ;<d7.b:相手の石
  969. ;<a5.l:置ける位置のリストの先頭
  970. ;>d0.l:置ける位置の数(0=どこにも置けない=パスまたは終局)
  971. ;>a1.l:置ける位置のリストの先頭
  972. ;>a5.l:置ける位置のリストの末尾(0の直後)
  973. ;>z-flag:eq=どこにも置けない=パスまたは終局
  974.     .text
  975.     .align    4,$2048
  976. list_ban:
  977.     movem.l    d1/a2,-(sp)
  978.     movea.l    a5,a1            ;置ける位置のリストの先頭
  979.     moveq.l    #0,d1            ;置ける位置の数
  980.     lea.l    (put_count_table,pc),a2
  981.     move.l    (a2)+,d0
  982. 1:    movea.l    d0,a0
  983.     tst.b    (a0)
  984.     bne    2f            ;石がある
  985.     bsr    put_test_ban
  986.     beq    2f            ;置けない
  987.     addq.w    #1,d1            ;置ける位置をカウント
  988.     move.l    a0,(a5)+        ;置ける位置のリストに加える
  989. 2:    move.l    (a2)+,d0
  990.     bne    1b
  991.     clr.l    (a5)+            ;置ける位置のリストの末尾
  992.     move.l    d1,d0
  993.     movem.l    (sp)+,d1/a2
  994.     rts
  995.  
  996. ;----------------------------------------------------------------
  997. ;自分の石を置ける位置を数える
  998. ;<d6.b:自分の石
  999. ;<d7.b:相手の石
  1000. ;>d0.l:置ける位置の数(0=どこにも置けない=パスまたは終局)
  1001. ;>z-flag:eq=どこにも置けない=パスまたは終局
  1002.     .text
  1003.     .align    4,$2048
  1004. count_ban::
  1005.     movem.l    d1/a0/a2,-(sp)
  1006.     moveq.l    #0,d1            ;置ける位置の数
  1007.     lea.l    (put_count_table,pc),a2
  1008.     move.l    (a2)+,d0
  1009. 1:    movea.l    d0,a0
  1010.     tst.b    (a0)
  1011.     bne    2f
  1012.     bsr    put_test_ban
  1013.     beq    2f
  1014.     addq.w    #1,d1            ;置ける位置をカウント
  1015. 2:    move.l    (a2)+,d0
  1016.     bne    1b
  1017.     move.l    d1,d0
  1018.     movem.l    (sp)+,d1/a0/a2
  1019.     rts
  1020.  
  1021. ;----------------------------------------------------------------
  1022.     .text
  1023.     .align    4,$2048
  1024. put_count_table:
  1025.     .dc.l    ban+P11,ban+P81,ban+P18,ban+P88    ;隅
  1026.     .dc.l    ban+P43,ban+P53,ban+P34,ban+P64    ;ボックスフィールド
  1027.     .dc.l    ban+P35,ban+P65,ban+P46,ban+P56
  1028.     .dc.l    ban+P42,ban+P52,ban+P24,ban+P74    ;Bの頭
  1029.     .dc.l    ban+P25,ban+P75,ban+P47,ban+P57
  1030.     .dc.l    ban+P33,ban+P63,ban+P36,ban+P66    ;ボックスコーナー
  1031.     .dc.l    ban+P31,ban+P61,ban+P13,ban+P83    ;A
  1032.     .dc.l    ban+P16,ban+P86,ban+P38,ban+P68
  1033.     .dc.l    ban+P32,ban+P62,ban+P23,ban+P73    ;Aの頭
  1034.     .dc.l    ban+P26,ban+P76,ban+P37,ban+P67
  1035.     .dc.l    ban+P41,ban+P51,ban+P14,ban+P84    ;B
  1036.     .dc.l    ban+P15,ban+P85,ban+P48,ban+P58
  1037.     .dc.l    ban+P21,ban+P71,ban+P12,ban+P82    ;C
  1038.     .dc.l    ban+P17,ban+P87,ban+P28,ban+P78
  1039.     .dc.l    ban+P22,ban+P72,ban+P27,ban+P77    ;星
  1040.     .dc.l    0
  1041.  
  1042. ;----------------------------------------------------------------
  1043. ;指定された位置に自分の石を置く
  1044. ;<d6.b:自分の石
  1045. ;<d7.b:相手の白
  1046. ;<a0.l:置く位置(空いているマスを指定すること)
  1047. ;>d0.w:ひっくり返せる石の数,0でなければ石を置ける
  1048. ;>z-flag:eq=置けない,ne=置ける
  1049.     .text
  1050.     .align    4,$2048
  1051. put_one:
  1052.     moveq.l    #0,d0            ;ひっくり返せる石の数
  1053.   .irp vect,V1,V2,V3,V4,V5,V6,V7,V8
  1054.     cmp.b    (vect*1,a0),d7
  1055.     bne    20f            ;隣が相手の石でないのでひっくり返せない
  1056.     cmp.b    (vect*2,a0),d7
  1057.     bne    11f            ;相手の石が1個だけ繋がっている
  1058.     cmp.b    (vect*3,a0),d7
  1059.     bne    12f            ;相手の石が2個だけ繋がっている
  1060.     cmp.b    (vect*4,a0),d7
  1061.     bne    13f            ;相手の石が3個だけ繋がっている
  1062.     cmp.b    (vect*5,a0),d7
  1063.     bne    14f            ;相手の石が4個だけ繋がっている
  1064.     cmp.b    (vect*6,a0),d7
  1065.     bne    15f            ;相手の石が5個だけ繋がっている
  1066.     bra    16f            ;相手の石が6個以上繋がっている
  1067.  
  1068. ;相手の石が1個だけ繋がっている
  1069. 11:    cmp.b    (vect*2,a0),d6
  1070.     bne    20f            ;自分の石で終わっていないのでひっくり返せない
  1071.     addq.w    #1,d0
  1072.     bra    21f
  1073.  
  1074. ;相手の石が2個だけ繋がっている
  1075. 12:    cmp.b    (vect*3,a0),d6
  1076.     bne    20f            ;自分の石で終わっていないのでひっくり返せない
  1077.     addq.w    #2,d0
  1078.     bra    22f
  1079.  
  1080. ;相手の石が3個だけ繋がっている
  1081. 13:    cmp.b    (vect*4,a0),d6
  1082.     bne    20f            ;自分の石で終わっていないのでひっくり返せない
  1083.     addq.w    #3,d0
  1084.     bra    23f
  1085.  
  1086. ;相手の石が4個だけ繋がっている
  1087. 14:    cmp.b    (vect*5,a0),d6
  1088.     bne    20f            ;自分の石で終わっていないのでひっくり返せない
  1089.     addq.w    #4,d0
  1090.     bra    24f
  1091.  
  1092. ;相手の石が5個だけ繋がっている
  1093. 15:    cmp.b    (vect*6,a0),d6
  1094.     bne    20f            ;自分の石で終わっていないのでひっくり返せない
  1095.     addq.w    #5,d0
  1096.     bra    25f
  1097.  
  1098. ;相手の石が6個以上繋がっている
  1099. 16:    cmp.b    (vect*7,a0),d6
  1100.     bne    20f            ;自分の石で終わっていないのでひっくり返せない
  1101.     addq.w    #6,d0
  1102. 26:    move.b    d6,(vect*6,a0)
  1103. 25:    move.b    d6,(vect*5,a0)
  1104. 24:    move.b    d6,(vect*4,a0)
  1105. 23:    move.b    d6,(vect*3,a0)
  1106. 22:    move.b    d6,(vect*2,a0)
  1107. 21:    move.b    d6,(vect*1,a0)
  1108. 20:
  1109.   .endm
  1110.     tst.w    d0
  1111.     beq    @f
  1112.     move.b    d6,(a0)
  1113.     tst.w    d0
  1114. @@:
  1115.     rts
  1116.  
  1117. ;----------------------------------------------------------------
  1118. ;指定された位置に自分の石を置いて変化した位置をレコードに記録する
  1119. ;<d6.b:自分の石
  1120. ;<d7.b:相手の石
  1121. ;<a0.l:置く位置(空いているマスを指定すること)
  1122. ;<a6.l:レコードの末尾(上位から下位に向かって記録する)
  1123. ;>d0.w:ひっくり返せる石の数,0でなければ石を置ける
  1124. ;>a6.l:レコードの先頭
  1125. ;    0.w    ひっくり返した石の数
  1126. ;    2.l    置いた位置(アドレス,置く前は空いていた)
  1127. ;    6.b    置いた石
  1128. ;    7.b    ひっくり返した石
  1129. ;    8.w    ひっくり返した石の位置(置いた位置からのオフセット)
  1130. ;     :
  1131. ;>z-flag:eq=置けない,ne=置ける
  1132.     .text
  1133.     .align    4,$2048
  1134. put_record_one::
  1135.     moveq.l    #0,d0            ;ひっくり返せる石の数
  1136.   .irp vect,V1,V2,V3,V4,V5,V6,V7,V8
  1137.     cmp.b    (vect*1,a0),d7
  1138.     bne    20f            ;隣が相手の石でないのでひっくり返せない
  1139.     cmp.b    (vect*2,a0),d7
  1140.     bne    11f            ;相手の石が1個だけ繋がっている
  1141.     cmp.b    (vect*3,a0),d7
  1142.     bne    12f            ;相手の石が2個だけ繋がっている
  1143.     cmp.b    (vect*4,a0),d7
  1144.     bne    13f            ;相手の石が3個だけ繋がっている
  1145.     cmp.b    (vect*5,a0),d7
  1146.     bne    14f            ;相手の石が4個だけ繋がっている
  1147.     cmp.b    (vect*6,a0),d7
  1148.     bne    15f            ;相手の石が5個だけ繋がっている
  1149.     bra    16f            ;相手の石が6個以上繋がっている
  1150.  
  1151. ;相手の石が1個だけ繋がっている
  1152. 11:    cmp.b    (vect*2,a0),d6
  1153.     bne    20f            ;自分の石で終わっていないのでひっくり返せない
  1154.     addq.w    #1,d0
  1155.     bra    21f
  1156.  
  1157. ;相手の石が2個だけ繋がっている
  1158. 12:    cmp.b    (vect*3,a0),d6
  1159.     bne    20f            ;自分の石で終わっていないのでひっくり返せない
  1160.     addq.w    #2,d0
  1161.     bra    22f
  1162.  
  1163. ;相手の石が3個だけ繋がっている
  1164. 13:    cmp.b    (vect*4,a0),d6
  1165.     bne    20f            ;自分の石で終わっていないのでひっくり返せない
  1166.     addq.w    #3,d0
  1167.     bra    23f
  1168.  
  1169. ;相手の石が4個だけ繋がっている
  1170. 14:    cmp.b    (vect*5,a0),d6
  1171.     bne    20f            ;自分の石で終わっていないのでひっくり返せない
  1172.     addq.w    #4,d0
  1173.     bra    24f
  1174.  
  1175. ;相手の石が5個だけ繋がっている
  1176. 15:    cmp.b    (vect*6,a0),d6
  1177.     bne    20f            ;自分の石で終わっていないのでひっくり返せない
  1178.     addq.w    #5,d0
  1179.     bra    25f
  1180.  
  1181. ;相手の石が6個以上繋がっている
  1182. 16:    cmp.b    (vect*7,a0),d6
  1183.     bne    20f            ;自分の石で終わっていないのでひっくり返せない
  1184.     addq.w    #6,d0
  1185. 26:    move.b    d6,(vect*6,a0)
  1186.     move.w    #vect*6,-(a6)
  1187. 25:    move.b    d6,(vect*5,a0)
  1188.     move.w    #vect*5,-(a6)
  1189. 24:    move.b    d6,(vect*4,a0)
  1190.     move.w    #vect*4,-(a6)
  1191. 23:    move.b    d6,(vect*3,a0)
  1192.     move.w    #vect*3,-(a6)
  1193. 22:    move.b    d6,(vect*2,a0)
  1194.     move.w    #vect*2,-(a6)
  1195. 21:    move.b    d6,(vect*1,a0)
  1196.     move.w    #vect*1,-(a6)
  1197. 20:
  1198.   .endm
  1199.     tst.w    d0
  1200.     beq    @f
  1201.     move.b    d6,(a0)
  1202.     move.b    d7,-(a6)        ;ひっくり返した石
  1203.     move.b    d6,-(a6)        ;置いた石
  1204.     move.l    a0,-(a6)        ;置いた位置
  1205.     move.w    d0,-(a6)        ;ひっくり返した石の数
  1206. @@:
  1207.     rts
  1208.  
  1209. ;----------------------------------------------------------------
  1210. ;置いた石を元に戻す
  1211. ;<a6.l:レコードの先頭
  1212. ;    0.w    ひっくり返した石の数
  1213. ;    2.l    置いた位置(アドレス,置く前は空いていた)
  1214. ;    6.b    置いた石
  1215. ;    7.b    ひっくり返した石
  1216. ;    8.w    ひっくり返した石の位置(置いた位置からのオフセット)
  1217. ;     :
  1218. ;>a6.l:レコードの末尾
  1219. ;?d0-d2/a0
  1220.     .text
  1221.     .align    4,$2048
  1222. tup_record_one:
  1223.     move.w    (a6)+,d1        ;ひっくり返した石の数
  1224.     movea.l    (a6)+,a0        ;置いた位置
  1225.     move.w    (a6)+,d2        ;下位バイト=ひっくり返した石
  1226.     subq.w    #1,d1
  1227. @@:    move.w    (a6)+,d0        ;ひっくり返した石の位置
  1228.     move.b    d2,(a0,d0.w)
  1229.     dbra    d1,@b
  1230.     sf.b    (a0)            ;置いた位置
  1231.     rts
  1232.  
  1233. ;----------------------------------------------------------------
  1234. ;指定された位置に自分の石を置けるか調べる
  1235. ;<d6.b:自分の石
  1236. ;<d7.b:相手の石
  1237. ;<a0.l:置く位置(空いているマスを指定すること)
  1238. ;>d0.w:ひっくり返せる石の数,0でなければ石を置ける
  1239. ;>z-flag:eq=置けない,ne=置ける
  1240.     .text
  1241.     .align    4,$2048
  1242. put_test_ban:
  1243.     moveq.l    #0,d0            ;ひっくり返せる石の数
  1244.   .irp vect,V1,V2,V3,V4,V5,V6,V7,V8
  1245.     cmp.b    (vect*1,a0),d7
  1246.     bne    20f            ;隣が相手の石でないのでひっくり返せない
  1247.     cmp.b    (vect*2,a0),d7
  1248.     bne    11f            ;相手の石が1個だけ繋がっている
  1249.     cmp.b    (vect*3,a0),d7
  1250.     bne    12f            ;相手の石が2個だけ繋がっている
  1251.     cmp.b    (vect*4,a0),d7
  1252.     bne    13f            ;相手の石が3個だけ繋がっている
  1253.     cmp.b    (vect*5,a0),d7
  1254.     bne    14f            ;相手の石が4個だけ繋がっている
  1255.     cmp.b    (vect*6,a0),d7
  1256.     bne    15f            ;相手の石が5個だけ繋がっている
  1257.     bra    16f            ;相手の石が6個以上繋がっている
  1258.  
  1259. ;相手の石が1個だけ繋がっている
  1260. 11:    cmp.b    (vect*2,a0),d6
  1261.     bne    20f            ;自分の石で終わっていないのでひっくり返せない
  1262.     addq.w    #1,d0
  1263.     bra    21f
  1264.  
  1265. ;相手の石が2個だけ繋がっている
  1266. 12:    cmp.b    (vect*3,a0),d6
  1267.     bne    20f            ;自分の石で終わっていないのでひっくり返せない
  1268.     addq.w    #2,d0
  1269.     bra    22f
  1270.  
  1271. ;相手の石が3個だけ繋がっている
  1272. 13:    cmp.b    (vect*4,a0),d6
  1273.     bne    20f            ;自分の石で終わっていないのでひっくり返せない
  1274.     addq.w    #3,d0
  1275.     bra    23f
  1276.  
  1277. ;相手の石が4個だけ繋がっている
  1278. 14:    cmp.b    (vect*5,a0),d6
  1279.     bne    20f            ;自分の石で終わっていないのでひっくり返せない
  1280.     addq.w    #4,d0
  1281.     bra    24f
  1282.  
  1283. ;相手の石が5個だけ繋がっている
  1284. 15:    cmp.b    (vect*6,a0),d6
  1285.     bne    20f            ;自分の石で終わっていないのでひっくり返せない
  1286.     addq.w    #5,d0
  1287.     bra    25f
  1288.  
  1289. ;相手の石が6個以上繋がっている
  1290. 16:    cmp.b    (vect*7,a0),d6
  1291.     bne    20f            ;自分の石で終わっていないのでひっくり返せない
  1292.     addq.w    #6,d0
  1293. 26:
  1294. 25:
  1295. 24:
  1296. 23:
  1297. 22:
  1298. 21:
  1299. 20:
  1300.   .endm
  1301.     tst.w    d0
  1302.     rts
  1303.  
  1304. ;----------------------------------------------------------------
  1305. ;定石探索
  1306. ;<d6.b:自分の石
  1307. ;<d7.b:相手の石
  1308. ;<a6.l:レコードの末尾(上位から下位に向かって記録する)
  1309. ;>d0.l:次の手(0=定石と一致しない)
  1310. ;>z-flag:eq=定石と一致しない
  1311.     .text
  1312.     .align    4,$2048
  1313. joseki:
  1314.     cmpi.w    #50,aki_count
  1315.     bhs    @f
  1316.     moveq.l    #0,d0
  1317.     rts
  1318. @@:
  1319.     movem.l    d1-d7/a0-a6,-(sp)
  1320.     move.b    d6,d5            ;自分の石
  1321. ;定石探索用の盤を初期状態にセットする
  1322.     lea.l    sban,a0
  1323.     lea.l    jban0,a3
  1324.     lea.l    (jban2-jban0,a3),a4
  1325.     moveq.l    #(BAN_LEN+3)/4-1,d1
  1326. 1:    move.l    (a0)+,d0
  1327.     move.l    d0,(a3)+
  1328.     move.l    d0,(jban1-jban0-4,a3)
  1329.     move.l    d0,(a4)+
  1330.     move.l    d0,(jban3-jban2-4,a4)
  1331.     dbra    d1,1b
  1332. ;定石の探索を行う
  1333.     moveq.l    #B,d6
  1334.     moveq.l    #W,d7
  1335.     lea.l    (jlist_01,pc),a2    ;定石データ
  1336.     lea.l    jban0,a3
  1337.     lea.l    (jban2-jban0,a3),a4
  1338.     movea.l    sp,a5
  1339.     bsr    joseki_sub
  1340.     moveq.l    #0,d0
  1341. joseki_exit:
  1342.     movem.l    (sp)+,d1-d7/a0-a6    ;レコードの末尾も復元すること
  1343.     rts
  1344.  
  1345. @@:    rts
  1346. joseki_sub:
  1347. 10:    moveq.l    #0,d2            ;上位ワードを0にしておく
  1348.     move.w    (a2)+,d2        ;X座標(1~8)
  1349.     beq    @b
  1350.     moveq.l    #0,d3            ;上位ワードを0にしておく
  1351.     move.w    (a2)+,d3        ;Y座標(1~8)
  1352.     cmp.b    d5,d6
  1353.     bne    40f            ;自分の番でなければ一致しないので比較を省略
  1354. ;定石通りに生成した盤と比較する
  1355.     lea.l    ban,a0
  1356.     movea.l    a3,a1
  1357.     bsr    compare_ban
  1358.     bne    30f
  1359. ;そのままの盤と一致した
  1360.     move.l    d2,d0            ;そのまま
  1361.     move.l    d3,d1
  1362. ;定石通りに生成した盤と一致した
  1363. ;<d0.w:X座標
  1364. ;<d1.w:Y座標
  1365. 20:    add.w    d1,d0
  1366.     lsl.w    #3,d1
  1367.     add.w    d1,d0
  1368.     movea.l    a5,sp
  1369.     bra    joseki_exit
  1370. 30:
  1371.     lea.l    ban,a0
  1372.     lea.l    (jban1-jban0,a3),a1
  1373.     bsr    compare_ban
  1374.     bne    30f
  1375. ;XとYを入れ替えた盤と一致した
  1376.     move.l    d3,d0            ;XとYを入れ替える
  1377.     move.l    d2,d1
  1378.     bra    20b
  1379. 30:
  1380.     lea.l    ban,a0
  1381.     movea.l    a4,a1
  1382.     bsr    compare_ban
  1383.     bne    30f
  1384. ;XとYをそれぞれ反転した盤と一致した
  1385.     moveq.l    #9,d0            ;XとYをそれぞれ反転する
  1386.     moveq.l    #9,d1
  1387.     sub.w    d2,d0
  1388.     sub.w    d3,d1
  1389.     bra    20b
  1390. 30:
  1391.     lea.l    ban,a0
  1392.     lea.l    (jban3-jban2,a4),a1
  1393.     bsr    compare_ban
  1394.     bne    30f
  1395. ;XとYをそれぞれ反転した上でXとYを入れ替えた盤と一致した
  1396.     moveq.l    #9,d0            ;XとYをそれぞれ反転した上でXとYを入れ替える
  1397.     moveq.l    #9,d1
  1398.     sub.w    d3,d0
  1399.     sub.w    d2,d1
  1400.     bra    20b
  1401. 30:
  1402.  
  1403. ;定石通りに生成した盤と一致しなかった
  1404. 40:
  1405.  
  1406. ;定石通りに盤を更新する
  1407.     move.l    (a2)+,d4
  1408.     beq    10b            ;次の手がないので更新する必要がない
  1409.     move.l    d2,d0            ;そのまま
  1410.     move.l    d3,d1
  1411.     add.w    d1,d0
  1412.     lsl.w    #3,d1
  1413.     add.w    d1,d0
  1414.     lea.l    (a3,d0.w),a0
  1415.     bsr    put_record_one
  1416.   .ifdef DEBUG
  1417.     beq    main_exit
  1418.   .endif
  1419.     move.l    d3,d0            ;XとYを入れ替える
  1420.     move.l    d2,d1
  1421.     add.w    d1,d0
  1422.     lsl.w    #3,d1
  1423.     add.w    d1,d0
  1424.     lea.l    (jban1-jban0,a3,d0.w),a0
  1425.     bsr    put_record_one
  1426.   .ifdef DEBUG
  1427.     beq    main_exit
  1428.   .endif
  1429.     moveq.l    #9,d0            ;XとYをそれぞれ反転する
  1430.     moveq.l    #9,d1
  1431.     sub.w    d2,d0
  1432.     sub.w    d3,d1
  1433.     add.w    d1,d0
  1434.     lsl.w    #3,d1
  1435.     add.w    d1,d0
  1436.     lea.l    (a4,d0.w),a0
  1437.     bsr    put_record_one
  1438.   .ifdef DEBUG
  1439.     beq    main_exit
  1440.   .endif
  1441.     moveq.l    #9,d0            ;XとYをそれぞれ反転した上でXとYを入れ替える
  1442.     moveq.l    #9,d1
  1443.     sub.w    d3,d0
  1444.     sub.w    d2,d1
  1445.     add.w    d1,d0
  1446.     lsl.w    #3,d1
  1447.     add.w    d1,d0
  1448.     lea.l    (jban3-jban2,a4,d0.w),a0
  1449.     bsr    put_record_one
  1450.   .ifdef DEBUG
  1451.     beq    main_exit
  1452.   .endif
  1453.     exg.l    d6,d7
  1454.     move.l    a2,-(sp)
  1455.     movea.l    d4,a2            ;次の手へ(0は既に除外してある)
  1456.     bsr    joseki_sub
  1457.     movea.l    (sp)+,a2
  1458.     exg.l    d6,d7
  1459.     bsr    tup_record_one
  1460.     bsr    tup_record_one
  1461.     bsr    tup_record_one
  1462.     bsr    tup_record_one
  1463.     bra    10b
  1464.  
  1465. ;定石データ
  1466. ;    牛     3 4 5 6
  1467. ;          6     3
  1468. ;         ●○     4
  1469. ;        5○●1 5
  1470. ;         432 6
  1471. ;
  1472. ;    兎     3 4 5 6
  1473. ;          5     3
  1474. ;         ●○4 4
  1475. ;        3○●1 5
  1476. ;         2     6
  1477. ;
  1478. ;    鼠     3 4 5 6
  1479. ;          3     3
  1480. ;         ●○2 4
  1481. ;        5○●1 5
  1482. ;         4     6
  1483.     .even
  1484. jlist_01:    .dc.w    6,5,jlist_02.l
  1485.         .dc.w    0
  1486. jlist_02:    .dc.w    6,6,jlist_13.l    ;牛
  1487.         .dc.w    4,6,jlist_23.l    ;兎
  1488.         .dc.w    6,4,jlist_33.l    ;鼠
  1489.         .dc.w    0
  1490. ;牛
  1491. jlist_13:    .dc.w    5,6,jlist_14.l
  1492.         .dc.w    0
  1493. jlist_14:    .dc.w    4,6,jlist_15.l
  1494.         .dc.w    0
  1495. jlist_15:    .dc.w    3,5,jlist_16.l
  1496.         .dc.w    0
  1497. jlist_16:    .dc.w    5,3,0.l
  1498.         .dc.w    0
  1499. ;兎
  1500. jlist_23:    .dc.w    3,5,jlist_24.l
  1501.         .dc.w    0
  1502. jlist_24:    .dc.w    6,4,jlist_25.l
  1503.         .dc.w    0
  1504. jlist_25:    .dc.w    5,3,0.l
  1505.         .dc.w    0
  1506. ;鼠
  1507. jlist_33:    .dc.w    5,3,jlist_34.l
  1508.         .dc.w    0
  1509. jlist_34:    .dc.w    4,6,jlist_35.l
  1510.         .dc.w    0
  1511. jlist_35:    .dc.w    3,5,0.l
  1512.         .dc.w    0
  1513.  
  1514.     .bss
  1515.     .align    4
  1516. jban0:        .ds.b    BAN_LEN
  1517.     .align    4
  1518. jban1:        .ds.b    BAN_LEN
  1519.     .align    4
  1520. jban2:        .ds.b    BAN_LEN
  1521.     .align    4
  1522. jban3:        .ds.b    BAN_LEN
  1523.     .align    4
  1524.  
  1525. ;----------------------------------------------------------------
  1526. ;盤を比較する
  1527. ;<a0.l:盤の先頭(4の倍数)
  1528. ;<a1.l:盤の先頭(4の倍数)
  1529. ;z-flag:eq=一致,ne=不一致
  1530. ;?a0-a1
  1531.     .text
  1532.     .align    4,$2048
  1533. compare_ban:
  1534.     lea.l    ((P11/4)*4,a0),a0
  1535.     lea.l    ((P11/4)*4,a1),a1
  1536.   .rept ((P88+3)/4)-(P11/4)        ;P88+3までは壁があるので盤からはみ出すことはない
  1537.     cmpm.l    (a0)+,(a1)+
  1538.     bne    @f
  1539.   .endm
  1540. @@:    rts
  1541.  
  1542. ;----------------------------------------------------------------
  1543. ;終盤の読み切り
  1544. ;    置ける場所がある状態で呼び出すこと
  1545. ;<d6.b:自分の石
  1546. ;<d7.b:相手の石
  1547. ;<a5.l:置ける位置のリストの先頭
  1548. ;<a6.l:レコードの末尾(上位から下位に向かって記録する)
  1549. ;>d0.l:次の手(0=定石と一致しない)
  1550. ;>z-flag:eq=定石と一致しない
  1551.     .text
  1552.     .align    4,$2048
  1553. yomikiri:
  1554.     move.w    aki_count,d0
  1555.     cmp.w    hisshou_level,d0
  1556.     bls    @f
  1557.     moveq.l    #0,d0
  1558.     rts
  1559. @@:
  1560.     movem.l    d1-d7/a0-a6,-(sp)
  1561. ;自分が置ける場所のリストを作る
  1562.     bsr    list_ban
  1563.     lea.l    eval_list,a2        ;リストの先頭(評価値が大きい順に並べる)
  1564.     movea.l    a2,a3
  1565.     clr.l    (a3)+            ;置く位置(番兵なので0)
  1566.     clr.l    (a3)+            ;次のセルへのポインタ(番兵なので無効)
  1567.     move.l    #$80000000,(a3)+    ;評価値(番兵なので最小値)
  1568.     move.l    (a1)+,d0        ;置く位置
  1569. 1:    movea.l    d0,a0            ;置く位置
  1570.     move.l    a0,(a3)            ;置く位置
  1571.     bsr    put_record_one
  1572.     exg.l    d6,d7
  1573.     bsr    eval            ;評価してみる
  1574.     exg.l    d6,d7
  1575.     neg.l    d0
  1576.     move.l    d0,(8,a3)        ;評価値
  1577.     movea.l    a2,a0            ;リストの先頭
  1578.     bra    16f
  1579. 15:    movea.l    a0,a4            ;直前のセルへのポインタ
  1580.     movea.l    (4,a0),a0
  1581. 16:    cmp.l    (8,a0),d0        ;評価値を比較
  1582.     ble    15b
  1583.     move.l    a0,(4,a3)        ;次のセルへのポインタ
  1584.     cmpa.l    a2,a0
  1585.     beq    17f
  1586.     move.l    a3,(4,a4)        ;直前のセルの次のセルへのポインタを更新する
  1587.     bra    18f
  1588. 17:    movea.l    a3,a2            ;リストの先頭を更新する
  1589. 18:    lea.l    (12,a3),a3        ;次の空きセル
  1590.     bsr    tup_record_one
  1591.     move.l    (a1)+,d0        ;置く位置
  1592.     bne    1b
  1593. ;石差と空きマス数を確認する
  1594.     bsr    get_sekisa
  1595.     move.w    d0,d5            ;石差(自分の石の数-相手の石の数)
  1596.     move.w    aki_count,d4        ;空きマス数
  1597.     subq.w    #1,d4            ;最初の手の分
  1598. ;α-β法で枝狩りしながら終局まで読み切る
  1599. ;必勝読み切りなので石差が1以上になる手が見つかったら終わり
  1600.     movea.w    #$8000,a3        ;α
  1601.     movea.w    #$7FFF,a4        ;β
  1602.     movea.l    a2,a1            ;置く位置のリストの先頭
  1603.     move.w    aki_count,d0
  1604.     cmp.w    kanzen_level,d0
  1605.     bls    kanzen            ;完全読み切りを行う
  1606.   .if 0
  1607.     moveq.l    #16,d0
  1608.     moveq.l    #0,d1
  1609.     bsr    locate
  1610.     moveq.l    #'*',d0
  1611.     bsr    putchar
  1612.     moveq.l    #100,d0
  1613.     bsr    wait_sec
  1614.   .endif
  1615.     move.l    (a1)+,d0        ;置く位置
  1616. 1:    movea.l    d0,a0            ;置く位置
  1617.     bsr    put_record_one
  1618.     add.w    d0,d5
  1619.     add.w    d0,d5
  1620.     addq.w    #1,d5
  1621.     exg.l    d6,d7
  1622. ;<d6.b:相手の石
  1623. ;<d7.b:自分の石
  1624.     bsr    hisshou_min        ;相手の手番で自分の石差の最小値を求める
  1625.     exg.l    d6,d7
  1626.     cmp.w    a3,d0
  1627.     ble    @f
  1628.     movea.l    a0,a2            ;相手の手番で自分の石差の最小値が最大になる手
  1629.     tst.w    d0
  1630.     bgt    3f            ;必勝読み切りのときは,
  1631.                     ;石差が1以上になる手が見つかったら終わり
  1632.     movea.w    d0,a3            ;αを更新
  1633. @@:    move.w    (a6),d0
  1634.     subq.w    #1,d5
  1635.     sub.w    d0,d5
  1636.     sub.w    d0,d5
  1637.     bsr    tup_record_one
  1638. 2:    movea.l    (a1)+,a1        ;次のセルへのポインタ(最後に番兵が出てくる)
  1639.     move.l    (a1)+,d0        ;置く位置(番兵のセルは0)
  1640.     bne    1b
  1641. ;必勝読み切りで石差が1以上になる手が見つからなかったときは,
  1642. ;石差がなるべく大きくなる手を選ぶ
  1643. 98:    move.l    a2,d0
  1644.     sub.l    #ban,d0
  1645. 99:    movem.l    (sp)+,d1-d7/a0-a6
  1646.     rts
  1647.  
  1648. 3:    move.w    (a6),d0
  1649.     subq.w    #1,d5
  1650.     sub.w    d0,d5
  1651.     sub.w    d0,d5
  1652.     bsr    tup_record_one
  1653.     bra    98b
  1654.  
  1655. ;完全読み切りを行う
  1656. kanzen:
  1657.   .if 0
  1658.     moveq.l    #16,d0
  1659.     moveq.l    #0,d1
  1660.     bsr    locate
  1661.     moveq.l    #'!',d0
  1662.     bsr    putchar
  1663.     moveq.l    #100,d0
  1664.     bsr    wait_sec
  1665.   .endif
  1666.     move.l    (a1)+,d0        ;置く位置
  1667. 1:    movea.l    d0,a0            ;置く位置
  1668.     bsr    put_record_one
  1669.     add.w    d0,d5
  1670.     add.w    d0,d5
  1671.     addq.w    #1,d5
  1672.     exg.l    d6,d7
  1673. ;<d6.b:相手の石
  1674. ;<d7.b:自分の石
  1675.     bsr    kanzen_min        ;相手の手番で自分の石差の最小値を求める
  1676.     exg.l    d6,d7
  1677.     cmp.w    a3,d0
  1678.     ble    @f
  1679.     movea.l    a0,a2            ;相手の手番で自分の石差の最小値が最大になる手
  1680.     movea.w    d0,a3            ;αを更新
  1681. @@:    move.w    (a6),d0
  1682.     subq.w    #1,d5
  1683.     sub.w    d0,d5
  1684.     sub.w    d0,d5
  1685.     bsr    tup_record_one
  1686. 2:    movea.l    (a1)+,a1        ;次のセルへのポインタ(最後に番兵が出てくる)
  1687.     move.l    (a1)+,d0        ;置く位置(番兵のセルは0)
  1688.     bne    1b
  1689. ;石差がなるべく大きくなる手を選ぶ
  1690.     move.l    a2,d0
  1691.     sub.l    #ban,d0
  1692. 99:    movem.l    (sp)+,d1-d7/a0-a6
  1693.     rts
  1694.  
  1695. ;----------------------------------------------------------------
  1696. ;自分の手番で自分の石差の最大値を求める(必勝読み切り)
  1697. ;<d4.w:空きマス数
  1698. ;<d5.w:石差(自分の石の数-相手の石の数)
  1699. ;<d6.b:自分の石
  1700. ;<d7.b:相手の石
  1701. ;<a3.l:α
  1702. ;<a4.l:β
  1703. ;>d0.w:石差(自分の石の数-相手の石の数)
  1704.     .text
  1705.     .align    4,$2048
  1706. @@:    move.w    d5,d0            ;石差(自分の石の数-相手の石の数)
  1707.     rts
  1708.     .align    4,$2048
  1709. hisshou_max:
  1710.     tst.w    d4
  1711.     beq    @b
  1712.     movem.l    d3-d4/a0-a1/a3/a5-a6,-(sp)
  1713.     bsr    list_ban        ;自分が置ける位置のリストを作る
  1714.     beq    5f            ;どこにも置けない(パスまたは終局)
  1715.     subq.w    #1,d4
  1716.     move.l    (a1)+,d0
  1717. 1:    movea.l    d0,a0
  1718.     bsr    put_record_one
  1719.     add.w    d0,d5
  1720.     add.w    d0,d5
  1721.     addq.w    #1,d5
  1722.     exg.l    d6,d7
  1723. ;<d6.b:相手の石
  1724. ;<d7.b:自分の石
  1725.     bsr    hisshou_min        ;相手の手番で自分の石差の最小値を求める
  1726.     exg.l    d6,d7
  1727.     cmp.w    a3,d0
  1728.     ble    @f
  1729.     movea.w    d0,a3            ;αを更新
  1730.     tst.w    d0
  1731.     bgt    3f            ;必勝読み切りのときは,
  1732.                     ;石差が1以上になる手が見つかったら終わり
  1733. @@:    move.w    (a6),d0
  1734.     subq.w    #1,d5
  1735.     sub.w    d0,d5
  1736.     sub.w    d0,d5
  1737.     bsr    tup_record_one
  1738.     cmpa.l    a4,a3
  1739.     bge    7f            ;α>=βなのでβカット
  1740. 2:    move.l    (a1)+,d0
  1741.     bne    1b
  1742. 98:    move.w    a3,d0            ;αを返す
  1743. 99:    movem.l    (sp)+,d3-d4/a0-a1/a3/a5-a6
  1744.     rts
  1745.  
  1746. 3:    move.w    (a6),d0
  1747.     subq.w    #1,d5
  1748.     sub.w    d0,d5
  1749.     sub.w    d0,d5
  1750.     bsr    tup_record_one
  1751.     bra    98b
  1752.  
  1753. ;どこにも置けない(パスまたは終局)
  1754. 5:    exg.l    d6,d7
  1755. ;<d6.b:相手の石
  1756. ;<d7.b:自分の石
  1757.     bsr    count_ban
  1758.     beq    6f            ;相手も置けないので終局
  1759.     bsr    hisshou_min        ;相手の手番で自分の石差の最小値を求める
  1760.     exg.l    d6,d7
  1761. ;<d6.b:自分の石
  1762. ;<d7.b:相手の石
  1763.     bra    99b
  1764.  
  1765. ;相手も置けないので終局
  1766. 6:    exg.l    d6,d7
  1767. ;<d6.b:自分の石
  1768. ;<d7.b:相手の石
  1769.     move.w    d5,d0            ;石差
  1770.     bra    99b
  1771.  
  1772. ;α>=βなのでβカット
  1773. ;親のαを返してはならない(評価値が同じだと選択されてしまうことがある)
  1774. 7:    move.w    #$3FFF,d0        ;絶対に選択されない
  1775.     bra    99b
  1776.  
  1777. ;----------------------------------------------------------------
  1778. ;相手の手番で自分の石差の最小値を求める(必勝読み切り)
  1779. ;<d4.w:空きマス数
  1780. ;<d5.w:石差(自分の石の数-相手の石の数)
  1781. ;<d6.b:相手の石
  1782. ;<d7.b:自分の石
  1783. ;<a3.l:α
  1784. ;<a4.l:β
  1785. ;>d0.w:石差(自分の石の数-相手の石の数)
  1786.     .text
  1787.     .align    4,$2048
  1788. @@:    move.w    d5,d0            ;石差(自分の石の数-相手の石の数)
  1789.     rts
  1790.     .align    4,$2048
  1791. hisshou_min:
  1792.     tst.w    d4
  1793.     beq    @b
  1794.     movem.l    d3-d4/a0-a1/a4/a5-a6,-(sp)
  1795.     bsr    list_ban        ;自分が置ける位置のリストを作る
  1796.     beq    5f            ;どこにも置けない(パスまたは終局)
  1797.     subq.w    #1,d4
  1798.     move.l    (a1)+,d0
  1799. 1:    movea.l    d0,a0
  1800.     bsr    put_record_one
  1801.     sub.w    d0,d5
  1802.     sub.w    d0,d5
  1803.     subq.w    #1,d5
  1804.     exg.l    d6,d7
  1805. ;<d6.b:自分の石
  1806. ;<d7.b:相手の石
  1807.     bsr    hisshou_max        ;自分の手番で自分の石差の最大値を求める
  1808.     exg.l    d6,d7
  1809.     cmp.w    a4,d0
  1810.     bge    @f
  1811.     movea.w    d0,a4            ;βを更新
  1812. @@:    move.w    (a6),d0
  1813.     addq.w    #1,d5
  1814.     add.w    d0,d5
  1815.     add.w    d0,d5
  1816.     bsr    tup_record_one
  1817.     cmpa.l    a3,a4
  1818.     ble    7f            ;β<=αなのでαカット
  1819. 2:    move.l    (a1)+,d0
  1820.     bne    1b
  1821. 98:    move.w    a4,d0            ;βを返す
  1822. 99:    movem.l    (sp)+,d3-d4/a0-a1/a4/a5-a6
  1823.     rts
  1824.  
  1825. ;どこにも置けない(パスまたは終局)
  1826. 5:    exg.l    d6,d7
  1827. ;<d6.b:自分の石
  1828. ;<d7.b:相手の石
  1829.     bsr    count_ban
  1830.     beq    6f            ;自分も置けないので終局
  1831.     bsr    hisshou_max        ;自分の手番で自分の石差の最大値を求める
  1832.     exg.l    d6,d7
  1833. ;<d6.b:相手の石
  1834. ;<d7.b:自分の石
  1835.     bra    99b
  1836.  
  1837. ;自分も置けないので終局
  1838. 6:    move.w    d5,d0            ;石差
  1839.     exg.l    d6,d7
  1840. ;<d6.b:相手の石
  1841. ;<d7.b:自分の石
  1842.     bra    99b
  1843.  
  1844. ;β<=αなのでαカット
  1845. ;親のβを返してはならない(評価値が同じだと選択されてしまうことがある)
  1846. 7:    move.w    #$C000,d0        ;絶対に選択されない
  1847.     bra    99b
  1848.  
  1849. ;----------------------------------------------------------------
  1850. ;自分の手番で自分の石差の最大値を求める(完全読み切り)
  1851. ;<d4.w:空きマス数
  1852. ;<d5.w:石差(自分の石の数-相手の石の数)
  1853. ;<d6.b:自分の石
  1854. ;<d7.b:相手の石
  1855. ;<a3.l:α
  1856. ;<a4.l:β
  1857. ;>d0.w:石差(自分の石の数-相手の石の数)
  1858.     .text
  1859.     .align    4,$2048
  1860. @@:    move.w    d5,d0            ;石差(自分の石の数-相手の石の数)
  1861.     rts
  1862.     .align    4,$2048
  1863. kanzen_max:
  1864.     tst.w    d4
  1865.     beq    @b
  1866.     movem.l    d3-d4/a0-a1/a3/a5-a6,-(sp)
  1867.     bsr    list_ban        ;自分が置ける位置のリストを作る
  1868.     beq    5f            ;どこにも置けない(パスまたは終局)
  1869.     subq.w    #1,d4
  1870.     move.l    (a1)+,d0
  1871. 1:    movea.l    d0,a0
  1872.     bsr    put_record_one
  1873.     add.w    d0,d5
  1874.     add.w    d0,d5
  1875.     addq.w    #1,d5
  1876.     exg.l    d6,d7
  1877. ;<d6.b:相手の石
  1878. ;<d7.b:自分の石
  1879.     bsr    kanzen_min        ;相手の手番で自分の石差の最小値を求める
  1880.     exg.l    d6,d7
  1881.     cmp.w    a3,d0
  1882.     ble    @f
  1883.     movea.w    d0,a3            ;αを更新
  1884. @@:    move.w    (a6),d0
  1885.     subq.w    #1,d5
  1886.     sub.w    d0,d5
  1887.     sub.w    d0,d5
  1888.     bsr    tup_record_one
  1889.     cmpa.l    a4,a3
  1890.     bge    7f            ;α>=βなのでβカット
  1891. 2:    move.l    (a1)+,d0
  1892.     bne    1b
  1893. 98:    move.w    a3,d0            ;αを返す
  1894. 99:    movem.l    (sp)+,d3-d4/a0-a1/a3/a5-a6
  1895.     rts
  1896.  
  1897. ;どこにも置けない(パスまたは終局)
  1898. 5:    exg.l    d6,d7
  1899. ;<d6.b:相手の石
  1900. ;<d7.b:自分の石
  1901.     bsr    count_ban
  1902.     beq    6f            ;相手も置けないので終局
  1903.     bsr    kanzen_min        ;相手の手番で自分の石差の最小値を求める
  1904.     exg.l    d6,d7
  1905. ;<d6.b:自分の石
  1906. ;<d7.b:相手の石
  1907.     bra    99b
  1908.  
  1909. ;相手も置けないので終局
  1910. 6:    exg.l    d6,d7
  1911. ;<d6.b:自分の石
  1912. ;<d7.b:相手の石
  1913.     move.w    d5,d0            ;石差
  1914.     bra    99b
  1915.  
  1916. ;α>=βなのでβカット
  1917. ;親のαを返してはならない(評価値が同じだと選択されてしまうことがある)
  1918. 7:    move.w    #$3FFF,d0        ;絶対に選択されない
  1919.     bra    99b
  1920.  
  1921. ;----------------------------------------------------------------
  1922. ;相手の手番で自分の石差の最小値を求める(完全読み切り)
  1923. ;<d4.w:空きマス数
  1924. ;<d5.w:石差(自分の石の数-相手の石の数)
  1925. ;<d6.b:相手の石
  1926. ;<d7.b:自分の石
  1927. ;<a3.l:α
  1928. ;<a4.l:β
  1929. ;>d0.w:石差(自分の石の数-相手の石の数)
  1930.     .text
  1931.     .align    4,$2048
  1932. @@:    move.w    d5,d0            ;石差(自分の石の数-相手の石の数)
  1933.     rts
  1934.     .align    4,$2048
  1935. kanzen_min:
  1936.     tst.w    d4
  1937.     beq    @b
  1938.     movem.l    d3-d4/a0-a1/a4/a5-a6,-(sp)
  1939.     bsr    list_ban        ;自分が置ける位置のリストを作る
  1940.     beq    5f            ;どこにも置けない(パスまたは終局)
  1941.     subq.w    #1,d4
  1942.     move.l    (a1)+,d0
  1943. 1:    movea.l    d0,a0
  1944.     bsr    put_record_one
  1945.     sub.w    d0,d5
  1946.     sub.w    d0,d5
  1947.     subq.w    #1,d5
  1948.     exg.l    d6,d7
  1949. ;<d6.b:自分の石
  1950. ;<d7.b:相手の石
  1951.     bsr    kanzen_max        ;自分の手番で自分の石差の最大値を求める
  1952.     exg.l    d6,d7
  1953.     cmp.w    a4,d0
  1954.     bge    @f
  1955.     movea.w    d0,a4            ;βを更新
  1956. @@:    move.w    (a6),d0
  1957.     addq.w    #1,d5
  1958.     add.w    d0,d5
  1959.     add.w    d0,d5
  1960.     bsr    tup_record_one
  1961.     cmpa.l    a3,a4
  1962.     ble    7f            ;β<=αなのでαカット
  1963. 2:    move.l    (a1)+,d0
  1964.     bne    1b
  1965. 98:    move.w    a4,d0            ;βを返す
  1966. 99:    movem.l    (sp)+,d3-d4/a0-a1/a4/a5-a6
  1967.     rts
  1968.  
  1969. ;どこにも置けない(パスまたは終局)
  1970. 5:    exg.l    d6,d7
  1971. ;<d6.b:自分の石
  1972. ;<d7.b:相手の石
  1973.     bsr    count_ban
  1974.     beq    6f            ;自分も置けないので終局
  1975.     bsr    kanzen_max        ;自分の手番で自分の石差の最大値を求める
  1976.     exg.l    d6,d7
  1977. ;<d6.b:相手の石
  1978. ;<d7.b:自分の石
  1979.     bra    99b
  1980.  
  1981. ;自分も置けないので終局
  1982. 6:    move.w    d5,d0            ;石差
  1983.     exg.l    d6,d7
  1984. ;<d6.b:相手の石
  1985. ;<d7.b:自分の石
  1986.     bra    99b
  1987.  
  1988. ;β<=αなのでαカット
  1989. ;親のβを返してはならない(評価値が同じだと選択されてしまうことがある)
  1990. 7:    move.w    #$C000,d0        ;絶対に選択されない
  1991.     bra    99b
  1992.  
  1993. ;----------------------------------------------------------------
  1994.     .data
  1995. ;盤の初期状態
  1996.     .align    4
  1997. sban:
  1998. ;          1 2 3 4 5 6 7 8
  1999.     .dc.b    _,_,_,_,_,_,_,_,_
  2000.     .dc.b    _,S,S,S,S,S,S,S,S    ;1
  2001.     .dc.b    _,S,S,S,S,S,S,S,S    ;2
  2002.     .dc.b    _,S,S,S,S,S,S,S,S    ;3
  2003.     .dc.b    _,S,S,S,W,B,S,S,S    ;4
  2004.     .dc.b    _,S,S,S,B,W,S,S,S    ;5
  2005.     .dc.b    _,S,S,S,S,S,S,S,S    ;6
  2006.     .dc.b    _,S,S,S,S,S,S,S,S    ;7
  2007.     .dc.b    _,S,S,S,S,S,S,S,S    ;8
  2008.     .dc.b    _,_,_,_,_,_,_,_,_,_
  2009.     .align    4
  2010. ;現在の盤
  2011.     .align    4
  2012. ban::
  2013. ;          1 2 3 4 5 6 7 8
  2014.     .dc.b    _,_,_,_,_,_,_,_,_
  2015.     .dc.b    _,S,S,S,S,S,S,S,S    ;1
  2016.     .dc.b    _,S,S,S,S,S,S,S,S    ;2
  2017.     .dc.b    _,S,S,S,S,S,S,S,S    ;3
  2018.     .dc.b    _,S,S,S,W,B,S,S,S    ;4
  2019.     .dc.b    _,S,S,S,B,W,S,S,S    ;5
  2020.     .dc.b    _,S,S,S,S,S,S,S,S    ;6
  2021.     .dc.b    _,S,S,S,S,S,S,S,S    ;7
  2022.     .dc.b    _,S,S,S,S,S,S,S,S    ;8
  2023.     .dc.b    _,_,_,_,_,_,_,_,_,_
  2024.     .align    4
  2025. ;スキャンマップ
  2026. ;    スキャンマップはbanから8ビットオフセットで届く位置に配置すること
  2027.     .align    4
  2028. map:    .dcb.b    BAN_LEN,0
  2029.     .align    4
  2030.  
  2031. ;得点表
  2032. ;    固定データだが、banからの相対アドレスで参照しやすいように.dataに配置する
  2033. ;    星の危険石>辺の危険石>中央の余裕手>辺の確定石>辺の余裕手
  2034. ;    辺5~6石確定>ウイングの減点
  2035.  
  2036. ;余裕手(空きで自分だけ置ける)の得点
  2037. yoyuu:        .dc.b    0,  0,  0,  0,  0,  0,  0,  0,  0
  2038.   .if 0
  2039.         .dc.b    0,255,  0, 20, 18, 18, 20,  0,255
  2040.         .dc.b    0,  0,  0, 14, 16, 16, 14,  0,  0
  2041.         .dc.b    0, 20, 14, 16, 18, 18, 16, 14, 20
  2042.         .dc.b    0, 18, 16, 18, 18, 18, 18, 16, 18
  2043.         .dc.b    0, 18, 16, 18, 18, 18, 18, 16, 18
  2044.         .dc.b    0, 20, 14, 16, 18, 18, 16, 14, 20
  2045.         .dc.b    0,  0,  0, 14, 16, 16, 14,  0,  0
  2046.         .dc.b    0,255,  0, 20, 18, 18, 20,  0,255
  2047.   .else
  2048.         .dc.b    0,255, 10, 10,  9,  9, 10, 10,255
  2049.         .dc.b    0, 10,  0,  7,  8,  8,  7,  0, 10
  2050.         .dc.b    0, 10,  7,  8,  9,  9,  8,  7, 10
  2051.         .dc.b    0,  9,  8,  9,  0,  0,  9,  8,  9
  2052.         .dc.b    0,  9,  8,  9,  0,  0,  9,  8,  9
  2053.         .dc.b    0, 10,  7,  8,  9,  9,  8,  7, 10
  2054.         .dc.b    0, 10,  0,  7,  8,  8,  7,  0, 10
  2055.         .dc.b    0,255, 10, 10,  9,  9, 10, 10,255
  2056.   .endif
  2057.         .dc.b    0,  0,  0,  0,  0,  0,  0,  0,  0,0
  2058.  
  2059. ;確定石(自分の石があって相手がひっくり返せない)の得点
  2060. kakutei:    .dc.b    0,  0,  0,  0,  0,  0,  0,  0,  0
  2061.   .if 0
  2062.         .dc.b    0,255,  0, 18, 16, 16, 18,  0,255
  2063.         .dc.b    0,  0,  0,  8,  8,  8,  8,  0,  0
  2064.         .dc.b    0, 18,  8,  8, 10, 10,  8,  8, 18
  2065.         .dc.b    0, 16,  8, 10, 10, 10, 10,  8, 16
  2066.         .dc.b    0, 16,  8, 10, 10, 10, 10,  8, 16
  2067.         .dc.b    0, 18,  8,  8, 10, 10,  8,  8, 18
  2068.         .dc.b    0,  0,  0,  8,  8,  8,  8,  0,  0
  2069.         .dc.b    0,255,  0, 18, 16, 16, 18,  0,255
  2070.   .else
  2071.         .dc.b    0,255,  0, 20, 15, 15, 20,  0,255
  2072.         .dc.b    0,  0,  0,  1,  1,  1,  1,  0,  0
  2073.         .dc.b    0, 20,  1,  1,  0,  0,  1,  1, 20
  2074.         .dc.b    0, 15,  1,  0,  0,  0,  0,  1, 15
  2075.         .dc.b    0, 15,  1,  0,  0,  0,  0,  1, 15
  2076.         .dc.b    0, 20,  1,  1,  0,  0,  1,  1, 20
  2077.         .dc.b    0,  0,  0,  1,  1,  1,  1,  0,  0
  2078.         .dc.b    0,255,  0, 20, 15, 15, 20,  0,255
  2079.   .endif
  2080.         .dc.b    0,  0,  0,  0,  0,  0,  0,  0,  0,0
  2081.  
  2082. ;危険石(自分の石があって相手がひっくり返せる)の減点
  2083. kiken:        .dc.b    0,  0,  0,  0,  0,  0,  0,  0,  0
  2084.   .if 0
  2085.         .dc.b    0,  0, 29, 29, 19, 19, 29, 29,  0
  2086.         .dc.b    0, 29,255,  9,  9,  9,  9,255, 29
  2087.         .dc.b    0, 29,  9,  1,  1,  1,  1,  9, 29
  2088.         .dc.b    0, 19,  9,  1,  1,  1,  1,  9, 19
  2089.         .dc.b    0, 19,  9,  1,  1,  1,  1,  9, 19
  2090.         .dc.b    0, 29,  9,  1,  1,  1,  1,  9, 29
  2091.         .dc.b    0, 29,255,  9,  9,  9,  9,255, 29
  2092.         .dc.b    0,  0, 29, 29, 19, 19, 29, 29,  0
  2093.   .else
  2094.         .dc.b    0,  0, 50, 15, 10, 10, 15, 50,  0
  2095.         .dc.b    0, 50,255, 10, 10, 10, 10,255, 50
  2096.         .dc.b    0, 15, 10,  1,  1,  1,  1, 10, 15
  2097.         .dc.b    0, 10, 10,  1,  1,  1,  1, 10, 10
  2098.         .dc.b    0, 10, 10,  1,  1,  1,  1, 10, 10
  2099.         .dc.b    0, 15, 10,  1,  1,  1,  1, 10, 15
  2100.         .dc.b    0, 50,255, 10, 10, 10, 10,255, 50
  2101.         .dc.b    0,  0, 50, 15, 10, 10, 15, 50,  0
  2102.   .endif
  2103.         .dc.b    0,  0,  0,  0,  0,  0,  0,  0,  0,0
  2104.  
  2105. ;----------------------------------------------------------------
  2106. ;石を置ける位置のリストとレコード
  2107.     .bss
  2108.     .align    4
  2109. put_list_top::    .ds.l    65536        ;先読みの深さに応じて大きくする必要がある
  2110. put_record_btm::
  2111.  
  2112. ;----------------------------------------------------------------
  2113. ;疑似乱数列の初期化
  2114.     .text
  2115.     .align    4,$2048
  2116. mysrand::
  2117.     move.l    d0,-(sp)
  2118.     DOS    _GETDATE
  2119.     move.l    d0,-(sp)
  2120.     DOS    _GETTIME
  2121.     add.l    (sp)+,d0
  2122.     move.l    d0,random_work
  2123.     move.l    (sp)+,d0
  2124.     rts
  2125.  
  2126.     .data
  2127.     .align    4
  2128. random_work:
  2129.     .dc.l    $FEDCBA98
  2130.  
  2131. ;----------------------------------------------------------------
  2132. ;疑似乱数の生成
  2133. ;>d0.l:乱数
  2134.     .text
  2135.     .align    4,$2048
  2136. myrand::
  2137.     move.l    d1,-(sp)
  2138.     move.l    random_work,d0
  2139.     move.l    d0,d1
  2140.     addq.l    #1,d0
  2141.     addq.l    #4,d1
  2142.     bsr    imul
  2143.     move.l    d1,random_work
  2144.     move.w    d1,d0
  2145.     swap.w    d0
  2146.     move.l    (sp)+,d1
  2147.     rts
  2148.  
  2149. ;----------------------------------------------------------------
  2150. ;32bit×32bit→64bit
  2151. ;<d0.l:被乗数
  2152. ;<d1.l:乗数
  2153. ;>d0.l:結果(上位)
  2154. ;>d1.l:結果(下位)
  2155. ;?d0-d1
  2156.     .text
  2157.     .align    4,$2048
  2158. imul::
  2159.     movem.l    d2-d4,-(sp)
  2160.     move.l    d0,d3
  2161.     move.l    d1,d4
  2162.     swap.w    d3
  2163.     swap.w    d4
  2164.     move.w    d3,d2
  2165.     mulu.w    d1,d2
  2166.     mulu.w    d0,d1
  2167.     mulu.w    d4,d0
  2168.     mulu.w    d3,d4
  2169.     add.l    d2,d0
  2170.     clr.w    d3
  2171.     addx.w    d3,d3
  2172.     swap.w    d1
  2173.     add.w    d0,d1
  2174.     swap.w    d1
  2175.     move.w    d3,d0
  2176.     swap.w    d0
  2177.     addx.l    d4,d0
  2178.     movem.l    (sp)+,d2-d4
  2179.     rts
  2180.  
  2181.